Question

I want to compare two class-manifests (gotten through implicits) to check if class A is extending trait B. The below code should yield true in the case where I ask if the class extends the interface:

trait X[T,S]

class Y extends X[Double,Int]


val mX = implicitly[ClassManifest[X[Double,Int]]]
val mY = implicitly[ClassManifest[Y]]

println(mX <:< mY)

println(mY <:< mX)

println(mX,mY)

However, I get the following output from the terminal:

felix@felix-UX32VD:~/Desktop$ scala Test.scala
false
false
(Main$$anon$1@7ad0e999.type#Main$$anon$1$X[Double, Int],Main$$anon$1@7ad0e999.type#Main$$anon$1$Y)

Can someone explain this behaviour?

Was it helpful?

Solution

The behavior of Manifests is broken. This is the reason why they are replaced with TypeTags in 2.10, which are working directly on the underlying types:

scala> typeTag[Y].tpe <:< typeTag[X[Double,Int]].tpe
res21: Boolean = true

scala> typeOf[Y] <:< typeOf[X[Double,Int]]
res22: Boolean = true

In 2.10 the idea was to deprecate the use of Manifests, but because the quality of the new reflection library is still not yet on the right level, this idea was declined. This means that Manifests still can be used but one still keep in back of one's mind that that they will be erased from the stdlib one day.

OTHER TIPS

It looks as if you are not actually interested in the subtype relation between the ClassManifests, but rather in the subtype relation between the erased types. Maybe this works for you:

println(mX <:< mY) // false
println(mX.erasure.isAssignableFrom(mY.erasure)) // true

println(mY <:< mX) // false
println(mY.erasure.isAssignableFrom(mX.erasure)) // false
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top