【问题标题】:HList to nested MapHList 到嵌套 Map
【发布时间】:2018-07-16 08:34:34
【问题描述】:

我想将 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

如果是 HNil 或具有 Dept L.size 的嵌套 Map 结构,则 f.Out 是 T

有什么办法可以做到吗?

【问题讨论】:

    标签: scala shapeless hlist


    【解决方案1】:

    我不知道进行这种转换的标准方法,但您可以像在 shapeless (see trait Mapper) 中实现各种 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

    【讨论】:

    • 感谢您的示例,我现在了解如何更好地构建自定义转换器!
    猜你喜欢
    • 1970-01-01
    • 2016-02-02
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    相关资源
    最近更新 更多