我开始使用无形状,作为概念证明,我定义了将Hlist转换为Map的功能,但是出了点问题,你能帮帮我吗?
object bar extends Poly1 {
implicit def caseTuple[T, U](implicit st: Case.Aux[T, Map[String, Any]], su: Case.Aux[U, Map[String, Any]]) =
at[(T, U)](t => {
Map(s"${t._1}" -> t._2)
})
}
object foo extends Poly2 {
implicit def default[T](implicit st: bar.Case.Aux[T, Map[String, Any]]) =
at[Map[String, Any], T] { (acc, t) =>
acc ++ bar(t)
}
}
val h = ("k1", 1) :: ("k2", "foo") :: HNil
println(h.foldLeft(Map.empty[String, Any])(foo))
但是我收到了错误:could not find implicit value for parameter folder: shapeless.ops.hlist.LeftFolder[shapeless.::[(String, Int),shapeless.::[(String, String),shapeless.HNil]],scala.collection.immutable.Map[String,Any],Main.foo.type]
[error] println(h.foldLeft(Map.empty[String, Any])(foo))
答案 0 :(得分:1)
由于您不关心值类型,因此您不需要为值类型提供专用的多态函数。
如果您只是依赖.toString
,则不需要Poly1
,以便上述示例可以像这样重写:
object foo1 extends Poly2 {
implicit def default[K, V] =
at[Map[String, Any], (K, V)] { case (acc, (k, v)) =>
acc + (k.toString -> v)
}
}
val h = ("k1", 1) :: ("k2", "foo") :: (true, "TRUE") :: HNil
println(h.foldLeft(Map.empty[String, Any])(foo1))
// Map(k1 -> 1, k2 -> foo, true -> TRUE)
Poly1
或提供scalaz.Show
的任何类别类,例如cats.Show
或A => String
。object bar2 extends Poly1 {
implicit val stringCase = at[String](identity)
implicit val symbolCase = at[Symbol](_.name)
implicit def integralCase[A: Integral] = at[A](_.toString)
implicit def fractionalCase[A: Fractional] = at[A](_ formatted "%.2f")
}
object foo2 extends Poly2 {
implicit def default[K, V](implicit bk: bar2.Case.Aux[K, String]) =
at[Map[String, Any], (K, V)] { case (acc, (k, v)) =>
acc + (bk(k) -> v)
}
}
val h2 = ("k1", 1) :: ("k2", "foo") :: ('k3, true) :: (12.3456, 'frac) :: HNil
println(h2.foldLeft(Map.empty[String, Any])(foo2))
// Map(k1 -> 1, k2 -> foo, k3 -> true, 12.35 -> 'frac)
您也可以使用其他密钥类型代替Any
。