Given the following types
trait N[X]
trait M[X, Y <: N[X]]
How does scala translate this:
M[_,_]
I've tried the following but without success:
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> typeOf[Class[_]] =:= typeOf[Class[C] forSome { type C }]
res4: Boolean = true
scala> typeOf[List[Class[_]]] =:= typeOf[List[Class[C] forSome { type C }]]
res5: Boolean = true
scala> typeOf[M[_,_]] =:= typeOf[M[X,Y] forSome { type X; type Y <: N[X] }]
res5: Boolean = false
warning: the existential type M[X,Y] forSome { type X; type Y <: N[X] }, which cannot be expressed by wildcards,
should be enabled by making the implicit value scala.language.existentials visible.
Quite puzzling? If it cannot be expressed by wildcards then the compiler should produce an error rather than a warning, shouldn't it?
Scala translates M[_,_]
into M[X, Y] forSome { type X; type Y }
. This is easily proven:
scala> type Foo = M[_,_]
defined type alias Foo
scala> type Bar = M[X, Y] forSome { type X; type Y }
defined type alias Bar
scala> implicitly[ Foo =:= Bar]
res0: =:=[Foo,Bar] = <function1>
Or using reflection:
scala> typeOf[Foo] =:= typeOf[Bar]
res2: Boolean = true
As for the warning you get, all it says is that M[X,Y] forSome { type X; type Y <: N[X] }
has no equivalent using wildcards. Wildcards are just syntactic sugar for a limited subset of existential types, and the scala compiler considers existentials an advanced feature that you should enable explicitly, hence the warning (unless the existential can be mapped to simple wildcards, which the compiler does not consider an advanced feature that would mandate to be explicitly enabled, which is why the warning mentions that the existential cannot be expressed by wildcards).