HList 到嵌套 Map [英] HList to nested Map

查看:45
本文介绍了HList 到嵌套 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆