Scala type projection with higher-kinded type
Asked Answered
R

1

5

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?

Rusticus answered 25/11, 2015 at 13:27 Comment(0)
W
7

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

Welltodo answered 25/11, 2015 at 14:6 Comment(1)
Didn't even know such thing as type variable existed. Learning new everyday. Thank you!Rusticus

© 2022 - 2024 — McMap. All rights reserved.