I’ve written the following function to check whether a given singleton class implements a trait.
/** 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 on the following example:
trait A
object B extends A
assert(maybeMakeSingletonObj[A](B.getClass()) === Some(B))
However, fails on the following example:
trait A[T, R]
object B extends A[Int, Int]
assert(maybeMakeSingletonObj[A[_,_]](B.getClass()) === Some(B))
Any ideas?
From ScalaDoc: “The type-relation operators <:< and =:= should be considered approximations only, as there are numerous aspects of type conformance which are not yet adequately represented in manifests.” Apparently, this is one such case.