Consider the following:
trait Foo {
type F[_]
type A
type FA = F[A]
def get: FA
}
class SeqStringFoo extends Foo {
type F[_] = Seq[_]
type A = String
def get: Seq[String] = Seq("hello world")
}
def exec[F <: Foo](foo: F): F#FA = foo.get
val seq1: Seq[Any] = exec(new SeqStringFoo()) // Seq[Any] = List(hello world)
val seq2: Seq[String] = exec(new SeqStringFoo()) // Error: Expression SeqIntFoo#FA doesn't conform to Seq[String]
seq2
doesn't compile since for some reason, type information of wrapped type String
is lost when using type projection F#FA
.
This doesn't happen when returned type isn't higher-kinded type.
Why does this happen?
How can I work around this?
Look like you just forgot pass type variable for F[_] in specialization, try:
class SeqStringFoo extends Foo {
type F[x] = Seq[x]
type A = String
def get: FA = Seq("hello world")
}
in other case you always return Seq[_]
( == Seq[Any]
) for any F[_]
(F[Int]
, F[String]
)