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?
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)
}