Search code examples
scalascala-macrosscala-3dottygeneric-derivation

Printing MirroredElemTypes in Scala 3


I am trying to modify this standard example to print values with the types. And I am stuck with p.MirroredElemTypes. I haven't found any API to traverse and stringify types.


Solution

  • To check MirroredElemTypes you can just summon

    import scala.deriving.Mirror
    
    case class A(i: Int, s: String, b: Boolean)
    
    val m = summon[Mirror.Of[A]]
    summon[m.MirroredElemTypes =:= (Int, String, Boolean)] // compiles
    

    But if you want to print MirroredElemTypes you can do the following.

    For some reason Typeable doesn't work now but in its error message it prints the type

    // scalaVersion := "3.0.2"
    // libraryDependencies += "org.typelevel" %% "shapeless3-typeable" % "3.0.3"
    import shapeless3.typeable.Typeable
    
    summon[Typeable[m.MirroredElemTypes]].describe
    // Typeable for sum type scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.*:[scala.Boolean, scala.Tuple$package.EmptyTuple]]] with no Mirror
    

    Alternatively you can write a simple macro

    import scala.quoted.*
    
    inline def describe[A]: String = ${describeImpl[A]}
    
    def describeImpl[T: Type](using Quotes): Expr[String] = {
      import quotes.reflect.*
      Literal(StringConstant(TypeRepr.of[T].dealias.show)).asExprOf[String]
    }
    
    // in a different file
    describe[m.MirroredElemTypes]
    // scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.*:[scala.Boolean, scala.Tuple$package.EmptyTuple]]]
    

    In Scala 3.2.0 + Shapeless 3.2.0 Typeable works properly

    https://scastie.scala-lang.org/DmytroMitin/1R6N3ZOJS46DJJqtQDU0lw