Scala reflection with parameterized types

I wrote the following function to check if a given singleton class implements a feature.

/** Given a singleton class, returns singleton object if cls implements T.                                                 
 * Else returns None. */
 def maybeMakeSingletonObj[T: ClassManifest](cls: Class[_]): Option[T] = {
   try {
     val m = classManifest[T]
     val obj = cls.getField("MODULE$").get(m.erasure).asInstanceOf[AnyRef]

     if (Manifest.singleType(obj) <:< m) Some(obj.asInstanceOf[T])
     else None
   } catch {
     case e: Exception => None
   }
 }

This code works fine in the following example:

trait A
object B extends A

assert(maybeMakeSingletonObj[A](B.getClass()) === Some(B)) 

However, the following example cannot be completed:

trait A[T, R]
object B extends A[Int, Int]

assert(maybeMakeSingletonObj[A[_,_]](B.getClass()) === Some(B))

Any ideas?

+5
source share
1 answer

From ScalaDoc : "Relationship operators such as <: <and =: = should only be considered approximations, since there are many aspects of type matching that are not yet sufficiently represented in the manifest." Apparently, this is one such case.

+3
source

All Articles