scalahigher-kinded-typestype-projection

Scala type projection with higher-kinded type


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?


Solution

  • 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])