Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala double definition (2 methods have the same type erasure)

I wrote this in scala and it won't compile:

class TestDoubleDef{   def foo(p:List[String]) = {}   def foo(p:List[Int]) = {} } 

the compiler notify:

[error] double definition: [error] method foo:(List[String])Unit and [error] method foo:(List[Int])Unit at line 120 [error] have same type after erasure: (List)Unit 

I know JVM has no native support for generics so I understand this error.

I could write wrappers for List[String] and List[Int] but I'm lazy :)

I'm doubtful but, is there another way expressing List[String] is not the same type than List[Int]?

Thanks.

like image 728
Jérôme Avatar asked Jul 22 '10 09:07

Jérôme


2 Answers

I like Michael Krämer's idea to use implicits, but I think it can be applied more directly:

case class IntList(list: List[Int]) case class StringList(list: List[String])  implicit def il(list: List[Int]) = IntList(list) implicit def sl(list: List[String]) = StringList(list)  def foo(i: IntList) { println("Int: " + i.list)} def foo(s: StringList) { println("String: " + s.list)} 

I think this is quite readable and straightforward.

[Update]

There is another easy way which seems to work:

def foo(p: List[String]) { println("Strings") } def foo[X: ClassTag](p: List[Int]) { println("Ints") } def foo[X: ClassTag, Y: ClassTag](p: List[Double]) { println("Doubles") } 

For every version you need an additional type parameter, so this doesn't scale, but I think for three or four versions it's fine.

[Update 2]

For exactly two methods I found another nice trick:

def foo(list: => List[Int]) = { println("Int-List " + list)} def foo(list: List[String]) = { println("String-List " + list)} 
like image 129
Landei Avatar answered Oct 11 '22 04:10

Landei


Instead of inventing dummy implicit values, you can use the DummyImplicit defined in Predef which seems to be made exactly for that:

class TestMultipleDef {   def foo(p:List[String]) = ()   def foo(p:List[Int])(implicit d: DummyImplicit) = ()   def foo(p:List[java.util.Date])(implicit d1: DummyImplicit, d2: DummyImplicit) = () } 
like image 45
Jean-Philippe Pellet Avatar answered Oct 11 '22 06:10

Jean-Philippe Pellet