通用#到,但有字段名称?

时间:2017-01-07 19:11:42

标签: scala shapeless

使用Generic#to,我可以获得HList的{​​{1}}代表:

case class

但是,我想得到以下代表:

import shapeless._ case class F(x: Int, y: String) scala> Generic[F].to( F(1, "foo") ) res1: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 1 :: foo :: HNil

换句话说,而不仅仅是("x", 1) :: ("y", "foo") :: HNil实例的字段'值,我想获取字段名称,即Fx

我怎样才能得到这种表述?

1 个答案:

答案 0 :(得分:5)

您正在寻找LabelledGeneric

为了打印字段,您可以使用Fields类型类(来自ops.record包),如果您同时导入{.fields,也可以使用record调用1}}包。

这是一个完整的例子

import shapeless._, record._, ops.record._
case class F(x: Int, y: String)    

scala> LabelledGeneric[F].to(F(1, "foo")).fields
res1: shapeless.::[(Symbol with shapeless.tag.Tagged[String("x")], Int),shapeless.::[(Symbol with shapeless.tag.Tagged[String("y")], String),shapeless.HNil]] = ('x,1) :: ('y,foo) :: HNil

如果您还想将密钥转换为String

object keysToString extends Poly1 {
  implicit def keyToName[A, B] = at[(Symbol with A, B)] { case (k, v) => (k.name, v) }
}

scala> LabelledGeneric[F].to(F(1, "foo")).fields.map(keysToString)
res2: shapeless.::[(String, Int),shapeless.::[(String, String),shapeless.HNil]] = (x,1) :: (y,foo) :: HNil