I have two subtypes that I need to be F-bounded polymorphic by a type A
, and a subtype of one of those subtypes, i.e.
trait A[T <: A[T]] {
def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter
Next I try to implement a concrete type
case class F2(l: List[A[_]]) extends For {
def x: For = F2(l.map(_.x))
}
But this fails to compile with:
<console>:11: error: type mismatch;
found : List[Any]
required: List[A[_]]
def x: For = F2(l.map(_.x))
^
So, google says I need to use existential types, which makes sense, so I try:
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))
}
But, now I face a new problem when I try to instantiate
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)
}
The compile error:
<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)
^
Why do I get this error? Surely C
is a subtype of Ter
, which in turn is a subtype of A[Ter]
, therefore C
is a subtype of A[Ter]
, therefore there exists a T
namely Ter
such that C
is a subtype of A[T]
, therefore C
is a subtype of SomeA
.
It's as if the transitivity of subtyping isn't working. When I hack it with c.asInstanceOf[SomeA]
my code compiles and my unit tests pass. Could it be a compiler bug?
I also thought that List[A[_]]
was stronger typing than List[SomeA]
, i.e. the former was saying the list consists of A[T]
some fixed type T
, where the latter is saying the list consists of A[T]
where T
is not fixed.
BOUNS If you can explain why the currently accepted answer works, i.e. why the compiler cannot work out that the type is valid without the ascription.
I guess the compiler needs some help. The following should work:
val l2 = List[SomeA](b, c: Ter, d)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With