2015-10-05 1 views
3

У меня возникла проблема с разрешением scala.reflect.Manifest для типа с типом.Разрешение `Manifest` для типа с типом

Например,

import scala.reflect.Manifest 

trait Foo { 
    type T 
} 

trait Bar[T] 

object Main extends App { 

    val barM: Manifest[Bar[Int]] = 
    implicitly[Manifest[Bar[Int]]] 

    val fooM: Manifest[Foo{type T = Int}] = 
    implicitly[Manifest[Foo{type T = Int}]] 

} 

Приведенный выше код не компилируется, что дает следующее сообщение об ошибке.

Foo.scala:15: error: type mismatch; 
found : scala.reflect.Manifest[Foo] 
required: scala.reflect.Manifest[Foo{type T = Int}] 
Note: Foo >: Foo{type T = Int}, but trait Manifest is invariant in type T. 
You may wish to investigate a wildcard type such as `_ >: Foo{type T = Int}`. (SLS 3.2.10) 
    implicitly[Manifest[Foo{type T = Int}]] 
      ^
one error found 

Но заявление barM работает очень хорошо.

Я знаю, что члены типа не являются параметрами типа, но я определенно не в курсе всех тонкостей.

Как можно решить проблему Manifest для типа с бетон тип члена?

+0

Похоже, что это может быть связано с этим, http://www.scala-lang.org/old/node/6550. – isomarcte

ответ

1

Структурные типы не поддерживаются Manifest. SI-4252 (Manifest структурных типов) обозначается как «не исправлять», и вместо этого рекомендуется использовать TypeTag. Manifest также скоро будет устаревшим.

scala> import scala.reflect.runtime.universe.TypeTag 
import scala.reflect.runtime.universe.TypeTag 

scala> implicitly[TypeTag[Foo { type T = Int} ]] 
res18: reflect.runtime.universe.TypeTag[Foo{type T = Int}] = TypeTag[Foo{type T = Int}] 

Вы могли бы также быть в состоянии работать вокруг этого с типом псевдоним, но это трудно сказать, без потребительной случае.

scala> type FooAux[T] = Foo { type T } 
defined type alias FooAux 

// Compiles, but is it useful? 
scala> implicitly[Manifest[FooAux[Int]]] 
res19: scala.reflect.Manifest[FooAux[Int]] = Foo 
+0

Я думал, что ваш ответ правильный, но теперь я не уверен. Это * не * структурный тип. Хотя синтаксис подобен, структурные типы излучают рефлексивные вызовы, чтобы проверить, что что-то правильно, в то время как это просто простые члены старого типа, без отражающих вызовов. – isomarcte

+0

Я уже пытался создать псевдоним типа. Увы, это не работает, так как компилятор все еще расстраивается из-за дисперсии члена типа. – isomarcte