我想創建一些特徵的列表,通過使用CRTP的類型進行參數化,並且無法弄清楚如何表達類型約束。這裏是一個能說明問題的一些示例代碼:如何表達類型約束更高kinded類型
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]
但也許我失去了一些東西。
所以問題是 - 什麼約束應該在emptyList函數來正確處理B?
我認爲這裏的問題是,你真正想要的是說'X [_ <:Z forAll {type Z <:A [Z]}]' - 即你想要一個更高等級的類型。不過,我還沒有制定出如何實現這個目標。 – Submonoid