【发布时间】:2015-07-26 23:02:12
【问题描述】:
继续讨论转换case classes 和Map[String,Any],当我想以通用方式使用它时遇到了一些问题,Here 是主要讨论。
当我想使用如下的泛型方法时,编译器会抱怨隐含:
import MapConvertor._
def convert[A](cc: A)= {
cc.toMapRec
}
这是提供toMapRec的完整代码:
import shapeless._, labelled.FieldType, record._
trait ToMapRec[L <: HList] { def apply(l: L): Map[String, Any] }
trait LowPriorityToMapRec {
implicit def hconsToMapRec1[K <: Symbol, V, T <: HList](implicit
wit: Witness.Aux[K],
tmrT: ToMapRec[T]
): ToMapRec[FieldType[K, V] :: T] =
new ToMapRec[FieldType[K, V] :: T] {
def apply(l: FieldType[K, V] :: T): Map[String, Any] =
tmrT(l.tail) + (wit.value.name -> l.head)
}
}
object ToMapRec extends LowPriorityToMapRec {
implicit val hnilToMapRec: ToMapRec[HNil] = new ToMapRec[HNil] {
def apply(l: HNil): Map[String, Any] = Map.empty
}
implicit def hconsToMapRec0[K <: Symbol, V, R <: HList, T <: HList](implicit
wit: Witness.Aux[K],
gen: LabelledGeneric.Aux[V, R],
tmrH: ToMapRec[R],
tmrT: ToMapRec[T]
): ToMapRec[FieldType[K, V] :: T] = new ToMapRec[FieldType[K, V] :: T] {
def apply(l: FieldType[K, V] :: T): Map[String, Any] =
tmrT(l.tail) + (wit.value.name -> tmrH(gen.to(l.head)))
}
}
object MapConvertor {
implicit class ToMapRecOps[A](val a: A) extends AnyVal {
def toMapRec[L <: HList](implicit
gen: LabelledGeneric.Aux[A, L],
tmr: ToMapRec[L]
): Map[String, Any] = tmr(gen.to(a))
}
}
【问题讨论】:
标签: scala generic-programming shapeless