你必须写一个宏
import shapeless.ops.hlist.Mapper
import shapeless.{Generic, HList, Poly1, Typeable}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
trait FieldTypes[A <: Product] {
type Out <: HList
}
object FieldTypes {
type Aux[A <: Product, Out0 <: HList] = FieldTypes[A] { type Out = Out0 }
implicit def mkFieldTypes[A <: Product, L <: HList](implicit
generic: Generic.Aux[A, L],
mapper: Mapper[typeablePoly.type, L]
): Aux[A, mapper.Out] = null
object typeablePoly extends Poly1 {
implicit def cse[A](implicit typeable: Typeable[A]): Case[A] = macro cseImpl[A]
def cseImpl[A: c.WeakTypeTag](c: whitebox.Context)(typeable: c.Tree): c.Tree = {
import c.universe._
val str = c.eval(c.Expr[String](c.untypecheck(q"$typeable.describe")))
val tpA = weakTypeOf[A]
q"null.asInstanceOf[FieldTypes.typeablePoly.Case.Aux[$tpA, _root_.shapeless.labelled.FieldType[$str, $tpA]]]"
}
}
}
测试:
import shapeless.{HNil, ::}
import shapeless.labelled.FieldType
implicitly[FieldTypes.Aux[Prod, FieldType["Int", Int] :: FieldType["String", String] :: HNil]]