Scala 是否可以将一个HMap从a型扩展到多个其他类型?

Scala 是否可以将一个HMap从a型扩展到多个其他类型?,scala,shapeless,Scala,Shapeless,用于强制异构映射的类型安全性,但它似乎不允许从某个类型映射到多个类型 换句话说,这是有效的: 类bimapi[K,V] 隐式val stringToInt=新的BIMAPI[String,Int] 隐式val intToString=新的BIMAPI[Int,String] val hm=HMap[bimapi](23->“foo”,“bar”->13) 但这不是: 类bimapi[K,V] 隐式val stringToInt=新的BIMAPI[String,Int] 隐式val string

用于强制异构映射的类型安全性,但它似乎不允许从某个类型映射到多个类型

换句话说,这是有效的:

类bimapi[K,V]
隐式val stringToInt=新的BIMAPI[String,Int]
隐式val intToString=新的BIMAPI[Int,String]
val hm=HMap[bimapi](23->“foo”,“bar”->13)
但这不是:

类bimapi[K,V]
隐式val stringToInt=新的BIMAPI[String,Int]
隐式val stringToString=new bimapi[String,String]
val hm=HMap[bimapi](“val1”->1,“val2”->2”)
我的问题是:是否有一种方法允许从一种类型(例如,
String
)到多种类型(例如,
String
Int
)的类型安全映射


另外,对于这个解决方案,我并没有嫁给Shapeless。

正确的方法需要一些管道:使用
CopProduct
列出所有可能的值:

class BiMapIS[K, V] { type Value = V }
implicit object strKey extends BiMapIS[String, Coproduct.`Int, String`.T]
implicit object intKey extends BiMapIS[Int,    Coproduct.`Boolean`.T]

val hm = HMap[BiMapIS](
  "val1" -> Coproduct[strKey.Value](1),
  "val2" -> Coproduct[strKey.Value]("two"),
  3      -> Coproduct[intKey.Value](true)
)
然后,您可以使自己成为一个有用的ops类,以便于从
HMap
中获取值:

implicit class HMapOps[R[_,_]](hm: HMap[R]) {
  def atKey[K,C <: Coproduct](k: K)(implicit ev1: R[K, C]) = new {
    def withValueType[V](implicit ev2: shapeless.ops.coproduct.Selector[C, V]): Option[V] = 
      hm.get(k).flatMap(_.select[V])
  }
}
隐式类hmapos[R[,]](hm:HMap[R]){
def atKey[K,C hm.atKey(“val1”)。带VALUETYPE[Int]
res1:Option[Int]=Some(1)
scala>hm.atKey(“val1”)。带ValueType[字符串]
res2:选项[字符串]=无
scala>hm.atKey(“val1”)。withValueType[Boolean]//字符串从不映射到Boolean!!!
:错误:找不到参数ev2:shapless.ops.copproduct.Selector的隐式值[shapless.:+:[Int,shapless.:+:[String,shapless.CNil]],布尔值]
hm.atKey(“val1”)。带ValueType[布尔值]
scala> hm.atKey("val1").withValueType[Int]
res1: Option[Int] = Some(1)

scala> hm.atKey("val1").withValueType[String]
res2: Option[String] = None

scala> hm.atKey("val1").withValueType[Boolean]   // String never maps to Boolean!!!
<console>: error: could not find implicit value for parameter ev2: shapeless.ops.coproduct.Selector[shapeless.:+:[Int,shapeless.:+:[String,shapeless.CNil]],Boolean]
       hm.atKey("val1").withValueType[Boolean]