How to access the `<:<` method

Continuing the discussion from Runtime reflection in Scala:

Can someone help me access the <:< method?

val data = List(1, 1.0, "hello", Array("hello",1.0))

val List(c1,c2,c3,c4) = data.map(_.getClass)

c1.<:<( c2)

c1 <:< c2

I get the following error.

Error:(5, 4) value <:< is not a member of Class[T]
c1.<:<( c2)

<:< is part of Scala reflection. getClass and Class are Java reflection.

The equivalent of <:< in Java reflection is isAssignableFrom:

scala 2.13.2> classOf[String].isAssignableFrom(classOf[Object])
val res3: Boolean = false

scala 2.13.2> classOf[Object].isAssignableFrom(classOf[String])
val res4: Boolean = true
3 Likes

So can I import something to get it? Maybe <:< first appears in 2.13?

You can define it

implicit class ClassOps[T](cls: Class[T]) {
  def <:< (cls1: Class[_]): Boolean = cls1 isAssignableFrom cls
}

c1 <:< c2 //false

Or you can use getType instead of getClass

import scala.reflect.runtime.universe._
def getType[A: TypeTag](a: A): Type = typeOf[A]

val List(c1,c2,c3,c4) = data.map(getType)

c1 <:< c2 // true

Notice that data has type List[Any] so both c1 and c2 are Any.

It’s old:

scala 2.11.12> :power
Power mode enabled. :phase is at typer.
import scala.tools.nsc._, intp.global._, definitions._
Try :help or completions for vals._ and power._

scala 2.11.12> typeOf[String] <:< typeOf[AnyRef]
res2: Boolean = true

scala 2.11.12> typeOf[AnyRef] <:< typeOf[String]
res3: Boolean = false

If you’re sure Scala reflection is what you want, it’s documented at https://docs.scala-lang.org/overviews/reflection/overview.html

Note that there’s also a class called <:<, which doesn’t involve any imports:

scala 2.11.12> implicitly[String <:< AnyRef]
res0: <:<[String,AnyRef] = <function1>

scala 2.11.12> implicitly[AnyRef <:< String]
<console>:12: error: Cannot prove that AnyRef <:< String.
               implicitly[AnyRef <:< String]
                         ^

You asked specifically about a method, but the class is much more commonly seen, so perhaps the class is what you meant.

What is it that you’re actually trying to do?

2 Likes

Something to underline in Seth’s latter example: AFAIK, <:< is mainly used in type signatures, to prove that a type relationship is correct at compile time. I hadn’t even realized it could be used at runtime…

1 Like

Or use ClassTag which already has such a method.

2 Likes

Thanks for the link. I think that’ll be useful. Is the reflection API something that is maintained from release to release? The document is marked as EXPERIMENTAL.

It will remain experimental for the lifetime of Scala 2.

It’s highly unlikely that the reflection API will undergo any really substantial changes in any future 2.x releases, but smaller changes (including breaking ones) remain possible.

1 Like