Scala 枚举到 HList 与无形

Scala Enumeration to HList with shapeless

假设有一个常规的 Scala 枚举对象,例如

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}

是否可以在不显式指定完整 HList 类型签名的情况下将其转换为无形 HList?我遇到了几乎是我需要的 ProductArgs,但它仍然需要将每个枚举值作为单独的参数提供。同时编译器确实知道枚举集合的类型和大小,所以它一定是可能的。

尝试

import shapeless.HList
import scala.language.experimental.macros
import scala.reflect.macros.whitebox

object Macros {
  object WeekDay extends Enumeration {
    type WeekDay = Value
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
  }

  trait ToHList {
    type T <: HList
  }

  def toHList(enum: Enumeration): ToHList = macro impl

  def impl(c: whitebox.Context)(enum: c.Tree): c.Tree = {
    import c.universe._
    val enum1 = c.eval(c.Expr[Enumeration](c.untypecheck(enum)))
    val valueNames = enum1.values.toList.map(_.toString)
    val tpe = valueNames.foldLeft[c.Tree](tq"shapeless.HNil")(
      (acc, v) => tq"shapeless.::[$enum.${TermName(v)}.type, $acc]"
    )
    q"new Macros.ToHList { type T = $tpe }"
  }
}

import Macros._
import shapeless.ops.hlist.Reify
val tohlist = toHList(WeekDay)
Reify[tohlist.T].apply() // Sun :: Sat :: Fri :: Thu :: Wed :: Tue :: Mon :: HNil