Is there a way to create a conversion of two equivalent types in Scala reflection into two equal types?

Consider the following:

scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> typeOf[Boolean] res23: reflect.runtime.universe.Type = Boolean scala> typeOf[scala.Boolean] res24: reflect.runtime.universe.Type = Boolean scala> res23 == res24 res25: Boolean = true scala> typeOf[java.lang.Boolean] res26: reflect.runtime.universe.Type = Boolean scala> res23 == res26 res27: Boolean = false scala> class Foo { def bf(arg: Boolean) = ??? } defined class Foo scala> typeOf[Foo] res28: reflect.runtime.universe.Type = Foo scala> res28.member(newTermName("bf")).asMethod res30: reflect.runtime.universe.MethodSymbol = method bf scala> res30.paramss.head.head res31: reflect.runtime.universe.Symbol = value arg scala> res31.typeSignature res32: reflect.runtime.universe.Type = scala.Boolean scala> res32 == res23 res33: Boolean = false scala> res32 =:= res23 res37: Boolean = true 

Thus, the type obtained using the typeOf [Boolean] function is equivalent to the type obtained by checking the method, but is not equal.

Is there a way to convert two equivalent types into some canonical representation where the results will be equal? I would like to use them for things like keys on cards.

Edit:

To be more clear, what I'm looking for is something like (not a real replix session):

 scala>val tp1 = // some type scala>val tp2 = // equivalent type obtained another way scala>tp1 == tp2 res1: Boolean = false scala>tp1 =:= tp2 res2: Boolean = true scala>val ctp1 = tp1.canonical scala>val ctp2 = tp2.canonical scala>ctp1 == ctp2 res3: Boolean = true scala>ctp1 =:= tp1 res4: Boolean = true scala>ctp2 =:= tp2 res5: Boolean = true 

Thus, equivalence is preserved by the transformation. I also need it to work with parameterized types.

+4
source share
2 answers

From the documentation :

It is important to note that == should not be used to compare types for equality - == cannot verify the equality of a type if there is an aliases type, but =:= can.

Of course, you can store the types in a list and use (for example) the following to check:

 myTypes.exists(_ =:= someType) 

You will see this approach in compiler source 2.10, for example. Of course, this is not as effective as a card or set, but you usually do not have many of these things in a collection.

If you absolutely need to have card or set performance, you can use erasure (as another answer suggests) or typeSymbol , depending on your requirements.

+4
source

erasure method scala.reflect.api.Types.TypeApi :

 typeOf[Foo].member(newTermName("bf")).asMethod.paramss.head.head .typeSignature.erasure == typeOf[Boolean] // res21: Boolean = true 
+2
source

All Articles