2015-11-25 5 views
4

Рассмотрим следующий пример:Скала тип проекции с более высоким-kinded типа

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 не компилируется, так как по какой-то причине, информация типа обернутого типа String теряется при использовании типа проекцииF#FA.

Этого не происходит, если возвращаемый тип не является более высокого класса.

Почему это происходит?

Как я могу обойти это?

ответ

6

Посмотрите, как вы просто забыли передать переменную типа для F [_] в специализации, попробуйте:

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

в другом случае вы всегда вернуться Seq[_] (== Seq[Any]) для любого F[_] (F[Int], F[String])

+1

Даже не знал, что существует такая вещь, как 'type variable'. Изучение нового повседневного. Спасибо! –