Неоднозначные неявные значения при использовании 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, или о функциональном программировании в целом) можно было бы рекомендовать, чтобы лучше понять всю тему, как я должен признать, у меня нет некоторого фона для этой темы.
1 ответ
Тип ключа определяет тип значения. У тебя есть Int
ключи, соответствующие обоим Node[Int]
а также Node[String]
ценности, отсюда и двусмысленность. Вы можете найти эту статью полезной для объяснения общего механизма, лежащего в основе этого.