HList 到嵌套 Map
HList to nested Map
我想将 HList 类型参数转换为嵌套的 Map 类型,例如Int :: String :: String :: HNil
应该变成 Map[Int, Map[String, Map[String, T]]]]
,其中 T 是同一函数的另一个类型参数,例如:
def somedef[T, L <: HList](t: T)(implicit f: ???): f.Out
其中 f.Out 在 HNil 或具有部门 L.size
的嵌套映射结构的情况下是 T
有什么办法可以做到吗?
我不知道执行此类转换的标准做法,但您可以采用与在 [=13] 内实现各种 HList 操作(如 map
)相同的方式推出自定义转换器=].代码可能是这样的:
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)
}
可以看到online
我想将 HList 类型参数转换为嵌套的 Map 类型,例如Int :: String :: String :: HNil
应该变成 Map[Int, Map[String, Map[String, T]]]]
,其中 T 是同一函数的另一个类型参数,例如:
def somedef[T, L <: HList](t: T)(implicit f: ???): f.Out
其中 f.Out 在 HNil 或具有部门 L.size
的嵌套映射结构的情况下是 T有什么办法可以做到吗?
我不知道执行此类转换的标准做法,但您可以采用与在 [=13] 内实现各种 HList 操作(如 map
)相同的方式推出自定义转换器=].代码可能是这样的:
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)
}
可以看到online