Search code examples
scalagenericstype-inferenceexistential-type

Scala existentials - type mismatch, unable to infer T =:= T


When using existential types in Scala, it seems the compiler infers each usage of the existential to be a different type parameter, even if they are actually the same.

For a simple contrived example - Given the following code

class Box[T](value:T){
  def get:T = value
  def contains(check:T):Boolean = value == check
}

I can do the following

val b1 = new Box(1)
b1.contains(b1.get)

However when using existential types...

 val b2 : Box[_] = new Box(1)
 b2.contains(b2.get)

I get the following error (In scala 2.11.7

[error] /private/tmp/exttest/test.scala:53: type mismatch;
[error]  found   : (some other)_$6(in value b2)
[error]  required: _$6(in value b2)
[error]   b2.contains(b2.get)

My assumption would be that the compiler would understand that the same type parameter _$6 is in use in both cases, however it seems to lose track and treat these as seperate types.

Am I fundamentally misunderstanding something about existential types, or is this a bug in the Scala compiler - and if so, is there a best-practice to work around it?


Solution

  • Another solution is to use type variable patterns to give a name to the wildcard and help Scala figure out they are the same:

    val b2 : Box[_] = new Box(1)
    b2 match {
      case b: Box[a] => b.contains(b.get)
    }