的例子中的細微變化給出了一個更實用的錯誤消息:
scala> l: (A[B] forSome { type B[_] })
<console>:10: error: type mismatch;
found : A[List]
required: A[_[_] <: Any]
Note: List <: Any, but trait A is invariant in type H.
You may wish to define H as +H instead. (SLS 4.5)
l: (A[B] forSome { type B[_] })
^
<console>:10: error: can't existentially abstract over parameterized type B
l: (A[B] forSome { type B[_] })
^
尋找這個錯誤給我們帶來的編譯器TODO。
由於存在類型是disappear,根據Odersky的電子郵件,我不認爲這個限制會被修復。然而,Martin Odersky的email也提醒我們存在類型等價於抽象類型。因此,如下上面的例子中可以被編碼:
scala> trait A { type H[_] }
defined trait A
scala> val l: A {type H[X] = List[X]} = null
l: A{type H[X] = List[X]} = null
scala> l: A
res0: A = null
類型應用在語法上是難看,但轉動一個值,一個存在變得微不足道(也以在一個編譯器,它是Odersky的的點的一部分實現)。
編碼存在的有用之處在於類型成員不必實例化。因此,編碼A[_]
我們可以這樣寫:
scala> class A { type T }
defined class A
scala> new A
res1: A = [email protected]
什麼困惑在這裏,這並不爲對象的工作:
scala> object B { type T }
<console>:8: error: only classes can have declared but undefined members
object B { type T }
^
但最近我接受了一個錯誤 - 見here的拉要求澄清規格(由Adriaan Moors批准),here爲我的錯誤報告和單線修復編譯器(仍在等待審查)。
我剛剛意識到錯誤在於賦值給x,所以現在我明白爲什麼你的示例會有意義。 – Blaisorblade