In an earlier post I already showed how to work around ambiguous method overloads resulting from type erasure. In a nut shell the following code wont compile since both overloaded methods foo erase to the same type.
Scala:
def foo(ints: List[Int]) {} def foo(strings: List[String]) {}
Java:
void foo(List<Integer> ints) {} void foo(List<String> strings) {}
It turns out that there is a simple though somewhat hacky way to work around this limitations: in order to make the ambiguity go away, we need to change the signature of foo in such a way that 1) the erasure of the foo methods are different and 2) the call site is not affected.
Here is a solution for Java:
void foo(List<Integer> ints, Integer... ignore) {} void foo(List<String> strings, String... ignore) {}
We can now call foo passing either a list of ints or a list of strings without ambiguity:
foo(new ArrayList<Integer>()); foo(new ArrayList<String>());
This doesn’t directly port over to Scala (why?). However, there is a similar hack for Scala. I leave this as a puzzle for a couple of days before I post my solution.
I would generally use typeclasses here:
sealed trait FooParam[A] {
def foo(xs: List[A])
}
implicit object FooIntParam extends FooParam[Int] {
def foo(xs: List[Int]) = …
}
implicit object FooStringParam extends FooParam[String] {
def foo(xs: List[String]) = …
}
def foo[A : FooParam](xs: List[A]) = implicitly[FooParam[A]] foo xs
Nice! I like this approach. It is at the same time a very clear and concise example for context bounds. I was always wondering why there is a special syntax for them. Your example makes this way clear!
My solution is closer to the Java code, but by far not as clean as yours.
[…] This post was mentioned on Twitter by Planet Scala and Javier Neira, Planet Lang. Planet Lang said: [Scala] Working around type erasure ambiguities: In an earlier post I already showed how to work around ambiguous … http://bit.ly/cvBnTL […]
Overload doesn’t work in scala because it implements varargs as Seq whereas java implements them with Arrays. Array[String] and Array[Int] erase to different types, but Seq[String] and Seq[Int] both erase to Seq.
nice post, thanks
[…] around type erasure ambiguities (Scala) 14 06 2010 In my previous post I showed a workaround for the type erasure ambiguity problem in Java. The solution uses vararg […]