Псевдонимы типов портят теги типов?

Почему теги типов не работают с псевдонимами типов. Например. данный

trait Foo
object Bar {
  def apply[A](implicit tpe: reflect.runtime.universe.TypeTag[A]): Bar[A] = ???
}
trait Bar[A]

Я хотел бы использовать псевдоним в следующем методе, потому что мне нужно ввести A около двух десятков раз:

def test {
  type A = Foo
  implicit val fooTpe = reflect.runtime.universe.typeOf[A] // no funciona
  Bar[A]                                                   // no funciona
}

Следующая попытка:

def test {
  type A = Foo
  implicit val fooTpe = reflect.runtime.universe.typeOf[Foo] // ok
  Bar[A]                                                     // no funciona
}

Так что, похоже, я вообще не могу использовать свой псевдоним.


person 0__    schedule 03.02.2013    source источник


Ответы (2)


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

person Eugene Burmako    schedule 05.02.2013
comment
Ok. Но нужно ли менять и сайт объявления? Потому что я, кажется, не получаю неявного преобразования из типа, возвращаемого weakTypeOf, в TypeTag[A]. Например. found : reflect.runtime.universe.Type ; required: reflect.runtime.universe.TypeTag[A] (при вызове Bar[A](fooTpe)) - person 0__; 05.02.2013
comment
Ладно, кажется, я что-то упустил, когда отвечал с телефона. Прежде всего, результатом typeOf и weakTypeOf является Type, а не TypeTag, поэтому fooTpe не вписывается в Bar.apply. - person Eugene Burmako; 05.02.2013
comment
Во-вторых, можно вообще избавиться от weakTypeOf и заменить TypeTag[A] на WeakTypeTag[A]. После этого он будет работать нормально. - person Eugene Burmako; 05.02.2013
comment
Хорошо, это работает, когда я использую оба weakTypeOf и WeakTypeTag. - person 0__; 05.02.2013

Изменить объявление def apply:

import scala.reflect.runtime.universe._
trait Foo
object Bar {
  def apply[A]()(implicit tpe: TypeTag[A]): Bar[A] = ???
}
trait Bar[A]
class test {
  type A = Foo
  implicit val foo = typeOf[A]
  def test = Bar[A]()                                                 
}
person idonnie    schedule 03.02.2013
comment
apply не имеет значения. Похоже, ваш пример работает, потому что вы перемещаете псевдоним типа на уровень члена класса (def test становится class test). Кажется, он как-то сломан как псевдоним локального типа метода - очень странно.... - person 0__; 04.02.2013