Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Created May 19, 2021 13:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubukoz/60117a3e00af108ae6933d153b7041cc to your computer and use it in GitHub Desktop.
Save kubukoz/60117a3e00af108ae6933d153b7041cc to your computer and use it in GitHub Desktop.
import scala.deriving.*
import scala.compiletime.*
inline def valuesOf[T <: Tuple]: List[String] = inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (h *: t) =>
erasedValue[h] match {
case label: String =>
label :: valuesOf[t]
}
}
inline def derived[T](using s: Mirror.SumOf[T]): Labels[T] =
a => valuesOf[s.MirroredElemLabels].toList(s.ordinal(a))
@kubukoz
Copy link
Author

kubukoz commented May 19, 2021

Better, but still with a cast:

  import scala.deriving.*
  import scala.compiletime.*

  inline def derived[T](using s: Mirror.SumOf[T]): Labels[T] =
    a => constValueTuple[s.MirroredElemLabels].toList.asInstanceOf[List[String]](s.ordinal(a))

@kubukoz
Copy link
Author

kubukoz commented May 19, 2021

Got it:

  import scala.deriving.*
  import scala.compiletime.*

  inline def derived[T](using s: Mirror.SumOf[T]): Labels[T] =
    a =>
      val labels = constValueTuple[s.MirroredElemLabels].toList
      val allStrings = summonInline[labels.type <:< List[String]]
      allStrings(labels)(s.ordinal(a))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment