使用HMap时的模糊隐含值

时间:2016-02-23 18:05:08

标签: scala shapeless

HMap似乎是我用例的完美数据结构,但是,我无法让它工作:

case class Node[N](node: N)

class ImplVal[K, V]
implicit val iv1 = new ImplVal[Int, Node[Int]]
implicit val iv2 = new ImplVal[Int, Node[String]]
implicit val iv3 = new ImplVal[String, Node[Int]]

val hm = HMap[ImplVal](1 -> Node(1), 2 -> Node("two"), "three" -> Node(3))

我的第一个问题是是否可以自动创建implicits vals。当然,对于典型的组合,我可以手动创建它们,但我想知道是否有更通用的,更少的样板方式。

接下来的问题是,如何从地图中获取值:

val res1 = hm.get(1) // (1) ambiguous implicit values: both value iv2 [...] and value iv1 [...] match expected type ImplVal[Int,V]`

对我而言,Node[Int](iv1)和Node[String](iv2)看起来非常不同:)我认为,尽管有JVM类型的擦除限制,但Scala可以在这里区分。我错过了什么?我是否必须使用其他隐式值来明确区别?

显式版本有效:

val res2 = hm.get[Int, Node[Int]](1) // (2) works

当然,在这个简单的例子中,我可以将类型信息添加到get调用中。但在下列情况下,只提前知道密钥,我不知道该怎么做:

def get[T <: HList](keys: T): HList = // return associated values for keys

这个问题有什么简单的解决方案吗?

顺便说一句,关于Scala的类型系统(或无形或一般的函数式编程)的哪些文档可以被推荐更好地理解整个主题,因为我不得不承认,我缺乏这个主题的一些背景知识。

1 个答案:

答案 0 :(得分:1)

键的类型决定了值的类型。您有Int个密钥对应于Node[Int]Node[String]值,因此存在歧义。您可能会发现this article有助于解释此基础的一般机制。