I got following problem. I would like to get the type as a string representation in scala 3. If I use following, I have the problem with type erasure.
object Example1:
@main def example1() =
print[String] // java.lang.String
print[Int] // int
print[List[Double]] // scala.collection.immutable.List => Dang it, Double is erased
def print[A: ClassTag]: Unit =
println(getTypeString[A])
def getTypeString[A](implicit ev: ClassTag[A]): String =
ev.runtimeClass.getTypeName
So far so known. So I tried to find TypeTag in scala 3 and found quoted.Type. Which worked great on the first look, but I run into trouble if I don't call the macro directly:
object Macro1:
import scala.quoted.*
inline def getTypeString[A]: String = ${ getTypeStringImpl[A] }
def getTypeStringImpl[A: Type](using Quotes): Expr[String] =
Expr(Type.show[A])
// In another file
object Example2:
@main def example2() =
println(Macro1.getTypeString[String]) // scala.Predef.String
println(Macro1.getTypeString[Int]) // scala.Int
println(Macro1.getTypeString[List[Double]]) // scala.collection.immutable.List[scala.Double] => Profit!
// Oh dang it...
print[String] // A
print[Int] // A
print[List[Double]] // A
def print[A]: Unit =
println(Macro1.getTypeString[A])
So the solution could be passing the Type through all functions as with ClassTag, but I can't make it compile:
object Macro2:
import scala.quoted.*
/* Dang it! This doesn't compile:
*
* Malformed macro parameter: evidence$3
*
* Parameters may only be:
* * Quoted parameters or fields
* * Literal values of primitive types
* * References to `inline val`s
*
* inline def getTypeString[A: Type]: String = ${ getTypeStringImpl[A] }
*/
inline def getTypeString[A: Type]: String = ${ getTypeStringImpl[A] }
def getTypeStringImpl[A: Type](using Quotes): Expr[String] =
Expr(Type.show[A])
// In another file
object Example3:
import scala.quoted.Type
@main def example3() =
print[String]
print[Int]
print[List[Double]]
def print[A: Type]: Unit =
println(Macro2.getTypeString[A])
Can anyone help me to make Example3 to compile? I tried different things, but non worked so far.