1
votes

I'm getting a compiler error that I don't understand. The code below produces the following error:

error: type mismatch; found : oldEntity.type (with underlying type com.mycompany.address.AddressEntity) required: $1 this.esDocsForAddressEntity.filter(.shouldTriggerRefresh(oldEntity, newEntity)).map(_.esDocName)

object AddressToEsDocMapper {


  private val esDocsForAddressEntity = List[EsDocRefreshTrigger[_]](new PartyAddressRefreshTrigger())


  def findEsDocsForUpdate(oldEntity : AddressEntity, newEntity : AddressEntity) : List[String] = {
    this.esDocsForAddressEntity.filter(_.shouldTriggerRefresh(oldEntity, newEntity)).map(_.esDocName)
  }


  private class PartyAddressRefreshTrigger extends EsDocRefreshTrigger[AddressEntity] {

    val esDocName = "PartyAddress"

    override def shouldTriggerRefresh(oldEntity : AddressEntity, newEntity : AddressEntity) : Boolean = {
      oldEntity.addressLine2 != newEntity.addressLine2 || 
      oldEntity.addressLine3 != newEntity.addressLine3 || 
      oldEntity.addressLine1 != newEntity.addressLine1
    }

  }

}
1

1 Answers

6
votes

You don't provide all the code, but presumably it's because you're using a wildcard in the definition of esDocsForAddressEntity. In solving for type params in the expression, it has no way to correlate oldEntity with the type arg of an arbitrary EsDocRefreshTrigger.

The $1 names are just internal or temporary names for the compiler.

Not a great example, but:

scala> val ss = List[Option[_]](Some("a"))
ss: List[Option[_]] = List(Some(a))

scala> ss filter (_.isDefined)
res2: List[Option[_]] = List(Some(a))

scala> ss filter (_.get.length > 0)
<console>:9: error: value length is not a member of _$1
              ss filter (_.get.length > 0)
                               ^

Brute force:

scala> class Foo { type A ; def foo(a: A) = 42 }
defined class Foo

scala> class Bar extends Foo { type A = Int }
defined class Bar

scala> class Baz extends Foo { type A = String }
defined class Baz

scala> val foos = List[Foo](new Bar, new Baz)
foos: List[Foo] = List(Bar@55cb6996, Baz@1807e3f6)

scala> foos map { case bar: Bar => bar foo 3 ; case baz: Baz => baz foo "three" }
res1: List[Int] = List(42, 42)

scala> def f(x: Foo)(a: x.A) = x foo a
f: (x: Foo)(a: x.A)Int

Or typeclass that supplies Bars and Bazes with foo methods.