I have trait with type parameter. To get the type of runtime, I use TypeTag . However, when this trait (and its classes) is used with the existential type in the collection, for example. List or Map , TypeTag "lost."
Here is an example of a standard way to use a type tag:
scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> trait Animal[T] { | def typeT()(implicit t: TypeTag[T]) = t.tpe | } defined trait Animal scala> scala> class Dog extends Animal[Int] defined class Dog scala> class Cat extends Animal[String] defined class Cat scala> scala> val dog = new Dog dog: Dog = Dog@4aa88c93 scala> val cat = new Cat cat: Cat = Cat@2281e252 scala> dog.typeT res46: reflect.runtime.universe.Type = Int scala> cat.typeT res47: reflect.runtime.universe.Type = String
As you can see how good this is, the typeT method defined and implemented in the Animal trait works. However, when used with List and existential types, it did not work:
scala> val aa: List[Animal[_]] = List(dog, cat, dog) aa: List[Animal[_]] = List( Dog@4aa88c93 , Cat@2281e252 , Dog@4aa88c93 ) scala> aa(0).typeT res52: reflect.runtime.universe.Type = _$1 scala> aa(1).typeT res53: reflect.runtime.universe.Type = _$1
Explicit casting (like the following) probably worked. But in most cases, List[Anima[_]] . If you need another level of TypeCast and how?
scala> aa(0) res55: Animal[_] = Dog@4aa88c93 scala> aa(0).asInstanceOf[Dog] res56: Dog = Dog@4aa88c93 scala> aa(0).asInstanceOf[Dog].typeT res57: reflect.runtime.universe.Type = Int
I understand that aa(0) is Animal[_] , which is the reason. But still aa(0) is not only Animal[_] , but also Dog . Why can't typeT (or TypeTag ) be used as if it were a regular method?
source share