4

I am writing a data structure (basically a hashmap) in Scala that will take one tuple (of possibly different number of arguments each time) and do something with it. To generically implement this, I defined a type:

type T <: Tuple1[_] with Tuple2[_,_] with Tuple3[_,_,_] with Tuple4[_,_,_,_] with Tuple5[_,_,_,_,_]

and then the data structure

val map = new HashMap[Int, T]

But this is ugly, since I have to change the type every time I have to handle more arguments in a tuple. Is there to define a generic tuple type?

Thanks, Y.K.

Y.K.
  • 397
  • 3
  • 16
  • 2
    Maybe you will be happy with `Product`? Yes, it allows to pass-in not only tuples, but it is pretty generic – om-nom-nom Dec 09 '12 at 09:38
  • Why do you restrict the value type of your data structure specifically to tuples? Do you intend to exploit some property common to all tuple types? – n. m. could be an AI Dec 09 '12 at 10:28
  • Thank you for your replies. I restrict the ds to tuples, since this is what the user will eventually enter (e.g. (3, 4.5, "foo")), and i want to avoid type conversions. I could use Product yes, however then I would have to have a regexp matching for the different types when i get each T back right? Something like varT match { case (_,_) => ... case (_,_,_) => ... } and so on... right? – Y.K. Dec 09 '12 at 10:35
  • 2
    I'm not sure I understand exactly what you're trying to do, but generalizing over tuple arity (without giving up type safety) is painful in Scala without the help of something like a heterogenous list implementation (I'd recommend [Shapeless](https://github.com/milessabin/shapeless)'s). – Travis Brown Dec 09 '12 at 12:03
  • I don't see which type conversions would be eliminated. Can you point out some? If the user will eventually enter (subtypes of) `Any`, would restricting `T` to `Any` eliminate type conversions? – n. m. could be an AI Dec 09 '12 at 13:16
  • @Y.K. what do you mean saying *I would have to have a regexp matching for the different types when i get each T back right*? You need to know exact class and parameterize function with it or what? – om-nom-nom Dec 09 '12 at 14:51

1 Answers1

4

The first solution is to use Product, as said by @om-nom-nom. Indeed, it's the only common supertype of all tuples.

val map = Map.empty[Int, Product]
map + (2 -> ("a", "b"))

And then to use the methods productArity, productElement and productIterator to handle the returned value.

You can also use a map of list (or any indexed collection).

val map = Map.empty[Int, List[_]]
map + (3 -> ("a" :: "b" :: "c" :: Nil))
map + (2 -> List("a", "b"))

The last solution is not that convenient for the user, but at least you know exactly what collection you handle. You could also add an implicit.

Lomig Mégard
  • 1,828
  • 14
  • 18