Search code examples
scalareflectioncase-classscala-reflectreify

TypeTag for case classes


I would like to make a case class Bla that takes a type parameter A and it knows the type of A at runtime (it stores it in its info field).

My attempt is shown in the example below. The problem is that this example does not compile.

case class Bla[A] (){
  val info=Run.paramInfo(this) // this does not compile
}
import scala.reflect.runtime.universe._

object Run extends App{
  val x=Bla[Int]
  def paramInfo[T](x:T)(implicit tag: TypeTag[T]): String = {
    val targs = tag.tpe match { case TypeRef(_, _, args) => args }
    val tinfo=s"type of $x has type arguments $targs"
    println(tinfo)
    tinfo
  }
  paramInfo(x)
}

However when I comment val info=Run.paramInfo(this) then the program runs fine and prints:

type of Bla() has type arguments List(Int)

Is there a way to make this example below compile ? (or in some other way achieve the same goal, i.e. that a case class is self aware of the type of it's type parameter?)


Solution

  • You just need to pass the implicit type tag parameter to the case class constructor (otherwise the type information is lost before calling paraInfo which requires it):

    case class Bla[A : TypeTag]() { ... }
    

    Which is shorthand for:

    case class Bla[A](implicit tag: TypeTag[A]) { ... }