I know that type erasure makes them look equal, type-wise, at runtime, so that:
class Bar {
def foo[A](xs: A*) { xs.foreach(println) }
def foo[A, B](xs: (A, B)*) { xs.foreach(x => println(x._1 + " - " + x._2)) }
}
gives the following compiler error:
<console>:7: error: double definition:
method foo:[A,B](xs: (A, B)*)Unit and
method foo:[A](xs: A*)Unit at line 6
have same type after erasure: (xs: Seq)Unit
def foo[A,B](xs: (A, B)*) { xs.foreach(x => println(x._1 + " - " + x._2)
) }
^
But is there a simple way to be able to write:
bar.foo(1, 2, 3)
bar.foo(1 -> 2, 3 -> 4)
and having these call different overloaded versions of foo, without having to explicitly name them:
bar.fooInts(1, 2, 3)
bar.fooPairs(1 -> 2, 3 -> 4)
You can, in a fairly round about way.
Foois a type class, and the compiler implcitly passes an instance of the type class, compatible with the (inferred) type parameterA.In the second call, both
FooAnyandFooTuple2could be passed, but the compiler picksFooTuple2, based on the rules of static method overloading.FooTuple2is considered more specific thatFooAny. If two candidates are considered to be as specific as each other, an ambiguity error is raised. You can also prefer one over the other by placing one in a superclass, as is done inscala.LowPriorityImplicits.UPDATE
Riffing off the DummyImplicit idea, and the followup thread on scala-user:
This declares a type-parameterized trait
__, covariant in its unnamed type parameter_. Its companion object__contains an implicit instance of__[Any], which we’ll need later on. The second and third overloads offooinclude a dummy type parameters, again unnamed. This will be inferred asAny. This type parameter has one or more context bounds, which are desugared into additional implicit parameters, for example:The multiple parameter lists are concatenated into a single parameter list in the bytecode, so the double definition problem is circumvented.
Please consider this as a opportunity to learn about erasure, context bounds and implicit search, rather than as a pattern to be applied in real code!