Working around type erasure ambiguities

30 05 2010

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.

Advertisements

Actions

Information

6 responses

30 05 2010
Daniel Spiewak

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

31 05 2010
michid

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.

30 05 2010
Tweets that mention Working around type erasure ambiguities « Michid’s Weblog -- Topsy.com

[…] 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 […]

31 05 2010
Paul Phillips

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.

14 06 2010
Ecko

nice post, thanks

14 06 2010
Working around type erasure ambiguities (Scala) « Michid’s Weblog

[…] 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 […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: