Tipos existentes para tipos polimórficos com limite de F e subtipos não genéricos?
Eu tenho dois subtipos que precisam ser polimórficos delimitados por F por um tipoA
, e um subtipo de um desses subtipos, ou seja,
trait A[T <: A[T]] {
def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter
Em seguida, tento implementar um tipo concreto
case class F2(l: List[A[_]]) extends For {
def x: For = F2(l.map(_.x))
}
Mas isso falha ao compilar com:
<console>:11: error: type mismatch;
found : List[Any]
required: List[A[_]]
def x: For = F2(l.map(_.x))
^
Então, o Google diz que preciso usar tipos existenciais, o que faz sentido, então tento:
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))
}
Mas agora enfrento um novo problema ao tentar instanciar
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)
}
O erro de compilação:
<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 que eu recebo esse erro? CertamenteC
é um subtipo deTer
, que por sua vez é um subtipo deA[Ter]
, PortantoC
é um subtipo deA[Ter]
, portanto, existe umT
nomeadamenteTer
de tal modo queC
é um subtipo deA[T]
, PortantoC
é um subtipo deSomeA
.
É como se a transitividade da subtipagem não estivesse funcionando. Quando eu corto comc.asInstanceOf[SomeA]
meu código é compilado e meus testes de unidade são aprovados. Poderia ser um bug do compilador?
Eu também pensei queList[A[_]]
foi mais forte digitação do queList[SomeA]
, ou seja, o primeiro dizia que a lista consiste emA[T]
algunsfixo tipoT
, onde este último está dizendo que a lista consiste emA[T]
OndeT
énão consertado.
BOUNS Se você pode explicarporque a resposta atualmente aceita funciona, ou seja, por que o compilador não pode descobrir se o tipo é válido sem a atribuição.