CRTPを使用する型によってパラメータ化されたいくつかの特性のリストを作成しようとしており、型制約の表現方法を理解できません。問題を説明するサンプルコードを次に示します。より上位の種類の型制約を表現する方法
trait A[X] {
def x: X
}
trait B[Y <: A[Y]] {
def y(i: Int): Y
}
case class C(i: Int) extends A[C] {
def x = C(i)
}
case class D(i: Int) extends A[D] {
def x = D(i)
}
case class E() extends B[C] {
def y(i: Int) = C(i)
}
case class F() extends B[D] {
def y(i: Int) = D(i)
}
object Program extends App {
def emptyList[X[_ <: Z forSome { type Z <: A[Z] } ]]() = collection.mutable.ListBuffer.empty[X[_]]
val myList = emptyList[B]()
myList += E()
myList += F()
println(myList.map(_.y(2).x))
}
ここで、B特性に準拠したオブジェクトのリストを作成しようとしています。しかし、このコードはコンパイルして、次のエラー与えません。私には
kinds of the type arguments (B) do not conform to the expected kinds of the type parameters (type X). B's type parameters do not match type X's expected parameters: type Y's bounds >: Nothing <: A[Y] are stricter than type _'s declared bounds >: Nothing <: Z forSome { type Z <: A[Z] } val myList = emptyList[B]()
を_ <: Z forSome { type Z <: A[Z] }
が実際Y <: A[Y]
と少なくとも同じくらい厳しいですが、多分私は何かが欠けてるように思えます。
したがって、問題は、Bが正しく処理されるためには、emptyList関数で制約がどうなるでしょうか。
ここで問題となるのは、あなたが本当に望むのは、X [_ <:Z forAll {type Z <:A [Z]}]です。私はこれを達成するためにどのように働いたのですか? – Submonoid