Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting MirroredElemLabels from Mirror

Scala 3's scala.deriving.Mirror has a type member MirroredElemLabels which is a tuple of string literals. What's the standard way to get that type as a value?

EDIT: here's the code that produces a compiler error from trying to use summonAll

case class Test(a: Int, b: String)
val mirror = implicitly[Mirror.ProductOf[Test]]
val labels = summonAll[mirror.MirroredElemLabels]
println(labels)

cannot reduce inline match with
 scrutinee:  compiletime.erasedValue[App.mirror.MirroredElemLabels] : App.mirror.MirroredElemLabels
 patterns :  case _:EmptyTuple
             case _:*:[t @ _, ts @ _]
like image 977
kag0 Avatar asked Dec 06 '25 20:12

kag0


1 Answers

Try to use scala.ValueOf

case class A(i: Int, s: String)

import scala.deriving.Mirror
import scala.compiletime.summonAll

val mirror = summon[Mirror.Of[A]]    
type ValueOfs = Tuple.Map[mirror.MirroredElemLabels, ValueOf]
val valueOfs = summonAll[ValueOfs]

def values(t: Tuple): Tuple = t match
  case (h: ValueOf[_]) *: t1 => h.value *: values(t1)
  case EmptyTuple => EmptyTuple

values(valueOfs) // (i,s)

We can now use scala.compiletime.constValueTuple

inline def constValueTuple[T <: Tuple]: T =
  (inline erasedValue[T] match
    case _: EmptyTuple => EmptyTuple
    case _: (t *: ts) => constValue[t] *: constValueTuple[ts]
  ).asInstanceOf[T]

and the return type will be precise

case class A(i: Int, s: String)

val mirror = summon[Mirror.Of[A]]

val res = constValueTuple[mirror.MirroredElemLabels] // (i,s)

res: ("i", "s") // compiles

Tested in 3.2.0

https://docs.scala-lang.org/scala3/reference/contextual/derivation.html

https://docs.scala-lang.org/scala3/reference/metaprogramming/compiletime-ops.html

like image 76
Dmytro Mitin Avatar answered Dec 08 '25 15:12

Dmytro Mitin