Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 969
Daniel Shin Avatar asked Nov 25 '15 13:11

Daniel Shin


1 Answers

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

like image 200
Yuriy Avatar answered Nov 15 '22 05:11

Yuriy