使用 HMap 时隐式值不明确
Ambiguous Implicit Values when using HMap
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 类型系统(或 Shapeless 或一般函数式编程)的文档来更好地理解整个主题,我不得不承认,我缺乏关于这个主题的一些背景知识。
键的类型决定了值的类型。您有 Int
键对应于 Node[Int]
和 Node[String]
值,因此存在歧义。您可能会发现 this article 有助于解释其背后的一般机制。
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 类型系统(或 Shapeless 或一般函数式编程)的文档来更好地理解整个主题,我不得不承认,我缺乏关于这个主题的一些背景知识。
键的类型决定了值的类型。您有 Int
键对应于 Node[Int]
和 Node[String]
值,因此存在歧义。您可能会发现 this article 有助于解释其背后的一般机制。