Scala projection type with a higher type 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]

seq2does not compile, because for some reason information of type wrapped type Stringis lost when using the type F#FA .

This does not happen if the return type is not of a higher type.

Why is this happening?

How can I get around this?

+4
source share
1 answer

It looks like you just forgot a pass variable for F [_] by specialization, try:

class SeqStringFoo extends Foo {
  type F[x] = Seq[x]
  type A = String
  def get: FA = Seq("hello world")
}

otherwise, you always return Seq[_](== Seq[Any]) for any F[_]( F[Int], F[String])

+6
source

Source: https://habr.com/ru/post/1617452/


All Articles