Sto cercando di creare un elenco di alcuni tratti, parametrizzati da un tipo utilizzando il CRTP e non riesco a capire come esprimere i vincoli di tipo. Ecco alcuni esempi di codice che illustra il problema:Come esprimere i vincoli di tipo per il tipo più elevato
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))
}
Così qui sto cercando di creare un elenco di oggetti conformi alla caratteristica B. Tuttavia questo codice non viene compilato, e dà il seguente errore:
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]()
A me sembra che _ <: Z forSome { type Z <: A[Z] }
è infatti almeno altrettanto rigorose Y <: A[Y]
ma forse mi manca qualcosa.
Quindi la domanda è: quali devono essere i vincoli sulla funzione emptyList per gestire correttamente B?
Credo che il problema qui è che cosa si vuole veramente è quello di dire 'X [_ <: Z FORALL {type Z <: A [Z]}]' - vale a dire che si desidera un tipo più alto rango. Non ho ancora capito come riuscirci! – Submonoid