This is the code for the blog entry implicit double dispatch revisited.
package michid;
object Converters2 {
abstract class Dispatcher[T](value: T) {
def dispatch()
def dispatch(l: List[T])
}
implicit def string2Disp(value: String) = new Dispatcher(value){
def dispatch() = println("String: " + value)
def dispatch(l: List[String]) = println("List[String]: " + l)
}
implicit def int2Disp(value: int) = new Dispatcher(value){
def dispatch() = println("Integer: " + value)
def dispatch(l: List[int]) = println("List[Integer]: " + l)
}
implicit def list2Disp[T](value: List[T])(implicit x2Disp: T => Dispatcher[T]) = new Dispatcher(value) {
def dispatch() = x2Disp(null.asInstanceOf[T]).dispatch(value)
def dispatch(l: List[List[T]]) = println("List[List[_]]: " + l)
}
}
object Poly2 {
import michid.Converters2._
def foo[T <% Dispatcher[T] forSome { type T <: List[_] }](x: T) = x.dispatch()
def main(args: Array[String]) {
val ints: List[int] = Nil
foo(ints)
val strings: List[String] = Nil
foo(strings)
// foo("A String") // Won't compile
// foo(42) // Won't compile
foo("one"::"two"::"three"::Nil)
foo(1::2::3::Nil)
foo((1::2::3::Nil)::(4::5::6::Nil)::Nil)
foo(("one"::"two"::Nil)::("three"::"four"::Nil)::Nil)
}
}
An alternate approach based on the same idea:
http://cleverlytitled.blogspot.com/2009/03/so-i-read-both-jim-mcbeath-and-michids.html