M[_,_] 的 Scala 存在占位符翻译,其中 M[X,Y <: N[X]]

Scala existentials placeholder translation for M[_,_] where M[X,Y <: N[X]]

给定以下类型

trait N[X]
trait M[X, Y <: N[X]]

scala 是如何翻译的:

M[_,_]

我尝试了以下但没有成功:

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.

很费解?如果它不能用通配符表示,那么编译器应该产生错误而不是警告,不是吗?

Scala 将 M[_,_] 翻译成 M[X, Y] forSome { type X; type Y }。这很容易证明:

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>

或使用反射:

scala> typeOf[Foo] =:= typeOf[Bar]
res2: Boolean = true

至于您收到的警告,它只是说 M[X,Y] forSome { type X; type Y <: N[X] } 没有使用通配符的等效项。通配符只是存在类型的有限子集的语法糖,scala 编译器认为存在是一种高级功能,您应该显式启用,因此警告(除非存在可以映射到简单的通配符,编译器不认为它是高级的将强制明确启用的功能,这就是警告中提到存在性不能用通配符表示的原因。