Неоднозначные неявные значения при использовании 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] ценности, отсюда и двусмысленность. Вы можете найти эту статью полезной для объяснения общего механизма, лежащего в основе этого.

Другие вопросы по тегам