recursive print field name in case class via shapeless

时间:2016-04-04 18:18:13

标签: scala shapeless

i have the next code:

trait X
case class Bar(id: Int) extends X
case class Foo(id: Int, bar: Bar) extends X 

i want to print all field for Foo with inner classes, i use shapeless for it, and create poly:

object print1 extends Poly1 {
  implicit def c[K, V](
    implicit wk: Witness.Aux[K]) = {
     at[FieldType[K, V]](field => {
      wk.value
    })
  }
}

val foo = Foo(1, Bar(10))
val fooLgen = LabeledGeneric[Foo]
pritnln(fooLgen.to(foo).map(print1)) // => 'id::'bar

But How to print with internal classes?

1 个答案:

答案 0 :(得分:3)

在您的示例中,您创建了一个HList个键,然后将其打印出来。您可以按如下方式递归执行:

trait LowerPriorityPrint1 extends Poly1 {
  implicit def c[K, V](implicit wk: Witness.Aux[K]) = {
    at[FieldType[K, V]](field => {
      wk.value
    })
  }
}

object print1 extends LowerPriorityPrint1 {
   implicit def csub[K, V, L <: HList](
     implicit l : LabelledGeneric.Aux[V, L],
               mapper : Mapper[print1.type, L]
              ) = {
    at[FieldType[K, V]](field => {
      l.to(field).map(print1)
    })
  }
}

val foo = Foo(1, Bar(10))
val fooLgen = LabelledGeneric[Foo]
println(fooLgen.to(foo).map(print1)) // => 'idFoo :: 'idBar :: HNil :: HNil

无形在编译时工作,因此您必须使用implicits在类型级别创建递归。同一个密钥同时存在ccSub,您可以通过在supertrait中声明优先级较低的密钥来决定首先解析哪个密钥