Tipos existenciales para tipos polimórficos con límite F y subtipos no genéricos?
Tengo dos subtipos que necesito que sean polimórficos limitados por F por un tipoA
, y un subtipo de uno de esos subtipos, es decir
trait A[T <: A[T]] {
def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter
Luego trato de implementar un tipo concreto
case class F2(l: List[A[_]]) extends For {
def x: For = F2(l.map(_.x))
}
Pero esto no se compila con:
<console>:11: error: type mismatch;
found : List[Any]
required: List[A[_]]
def x: For = F2(l.map(_.x))
^
Entonces, Google dice que necesito usar tipos existenciales, lo cual tiene sentido, así que intento:
import scala.language.existentials
type SomeA = T forSome { type T <: A[T] }
case class F1(l: List[SomeA]) extends For {
def x: For = F1(l.map(_.x))
}
Pero ahora me enfrento a un nuevo problema cuando intento crear una instancia
trait Example {
val b: Ter
val c: C
val d: For
// Works fine
val l1: List[A[_]] = List(b, c, d)
// But this doesn't work, fails to compile (see below)
val l2: List[SomeA] = List(b, c, d)
val f1 = F1(l2)
}
El error de compilación:
<console>:22: error: type mismatch;
found : C
required: SomeA
(which expands to) T forSome { type T <: A[T] }
val l2: List[SomeA] = List(b, c, d)
^
¿Por qué recibo este error? SeguramenteC
es un subtipo deTer
, que a su vez es un subtipo deA[Ter]
, por lo tantoC
es un subtipo deA[Ter]
, por lo tanto existe unT
a saberTer
tal queC
es un subtipo deA[T]
, por lo tantoC
es un subtipo deSomeA
.
Es como si la transitividad del subtipo no funcionara. Cuando lo pirateo conc.asInstanceOf[SomeA]
mi código se compila y mis pruebas unitarias pasan. ¿Podría ser un error del compilador?
También pensé queList[A[_]]
fue más fuerte escribiendo queList[SomeA]
, es decir, el primero decía que la lista consta deA[T]
algunosfijo tipoT
, donde este último dice que la lista consiste enA[T]
dóndeT
esno arreglado.
BOUNS Si puedes explicarpor qué la respuesta actualmente aceptada funciona, es decir, por qué el compilador no puede determinar que el tipo es válido sin la adscripción.