HList 到嵌套 Map [英] HList to nested Map
问题描述
我想将 HList 类型参数转换为嵌套的 Map 类型,例如Int :: String :: String :: HNil
应该变成 Map[Int, Map[String, Map[String, T]]]]
其中 T 将是另一个类型参数具有相同功能,例如:
I would like to transform an HList type parameter to a nested Map-type, e.g. Int :: String :: String :: HNil
should become Map[Int, Map[String, Map[String, T]]]]
where T would be another type parameter of the same function, like:
def somedef[T, L <: HList](t: T)(隐式 f: ???): f.Out
如果是 HNil 或带有 L.size 的嵌套 Map 结构,则 f.Out 是 T
where f.Out is T in case of HNil or a nested Map-structure with dept L.size
有什么办法可以做到吗?
Is there any way this can be done?
推荐答案
我不知道进行这种转换的标准做法,但是您可以采用与各种 HList 操作(例如map
) 在 无形(参见trait Mapper
).代码可能是这样的:
I'm not aware of a standard thing to do such a transformation, but you could roll out your custom converter in the same way as various HList ops (like map
) are implemented inside shapeless (see trait Mapper
). The code could be something like this:
import scala.language.higherKinds
import scala.collection.immutable.Map
import shapeless._
sealed trait HListToMap[L <: HList, T] {
type Out
def convert(hlist: L, value: T): Out
}
object HListToMap {
// public interface
def wrap[L <: HList, T](value: T, keys: L)(implicit converter: HListToMap[L, T]): converter.Out =
converter.convert(keys, value)
// implementation details
type Aux[L <: HList, T, Out2] = HListToMap[L, T] { type Out = Out2 }
private trait Impl[L <: HList, T, Out2] extends HListToMap[L, T] {
override type Out = Out2
}
implicit def hnil[T]: Aux[HNil, T, T] = new Impl[HNil, T, T] {
override def convert(hlist: HNil, value: T): T = value
}
implicit def hnil2[T]: Aux[HNil.type, T, T] = new Impl[HNil.type, T, T] {
override def convert(hlist: HNil.type, value: T): T = value
}
implicit def recurse[H, L <: HList, T](implicit inner: HListToMap[L, T]): Aux[H :: L, T, Map[H, inner.Out]] = new Impl[H :: L, T, Map[H, inner.Out]] {
override def convert(hlist: H :: L, value: T): Map[H, inner.Out] = {
val im = inner.convert(hlist.tail, value)
Map(hlist.head -> im)
}
}
}
def test(): Unit = {
val keys = "abc" :: 1 :: 0.5 :: HNil
val value = "Xyz"
val m: Map[String, Map[Int, Map[Double, String]]] = HListToMap.wrap(value, keys)
println(m)
val just: String = HListToMap.wrap(value, HNil)
println(just)
}
您可以在线
这篇关于HList 到嵌套 Map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!