0

HMap seems to be the perfect data structure for my use case, however, I can't get it working:

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))

My first question is whether it is possible to create those implicits vals automatically. For sure, for typical combinations I could create them manually, but I'm wondering if there is something more generic, less boilerplate way.

Next question is, how to get values out of the map:

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

To me, Node[Int] (iv1) and Node[String] (iv2) look pretty different :) I thought, despite the JVM type erasure limitations, Scala could differentiate here. What am I missing? Do I have to use other implicit values to make the difference clear?

The explicit version works:

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

Of course, in this simple case, I could add the type information to the get call. But in the following case, where only the keys are known in advance, I don't know how to do it:

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

Is there any simple solution to this problem?

BTW, what documentation about Scala's type system (or Shapeless or in functional programming in general) could be recommended to understand the whole topic better as I have to admit, I'm lacking some background for this topic.

user3127060
  • 1,493
  • 2
  • 10
  • 10

1 Answers1

1

The type of the key determines the type of the value. You have Int keys corresponding to both Node[Int] and Node[String] values, hence the ambiguity. You might find this article helpful in explaining the general mechanism underlying this.

Miles Sabin
  • 23,015
  • 6
  • 61
  • 95
  • Yes, your article gave me the necessary background. I thought that [Int, Node[Int]] and [Int, Node[String]] would be considered entirely. Given the explanations about FunDeps make it clear that "the type of the key determines the type of the value", which leads to the ambiguity in my case. Hence, it is not possible with `HMap` to let a few keys of type `K` map to values of type `V1`and other keys of type `K` to values of type `V2`. Unfortunately, this would be exactly the functionality I need, so I have to mimic it somehow different. – user3127060 Feb 25 '16 at 14:39