Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

method overloading with a parameterized type

Tags:

scala

Just wondering if there is a way to call an overloaded method using a parameterized type. For example define the following object:

object Wrap {

        def f(x: X) = println("x called")
        def f(y: Y) = println("y called")
        def f(a: Any) = println("Any")

        def fp[T](t: T) = f(t)
}

When I test this making the following call

Wrap.fp(new X())

it goes to the call to the Any. Is there a way I can work it such that the appropriate f is called from fp()?

like image 241
user79074 Avatar asked Mar 21 '23 00:03

user79074


1 Answers

Two ways to do it:

First way assumes that X and Y are known types and not generic types. Then you could just do the following:

 def fp: PartialFunction[Any,Unit] ={
   case x: X => println("got x")
   case y: Y => println("got y")
   case _ => println("Any")
 }

and it would work very well without having to do much gymanistics.

Second way, use a type class:

 def fp[T](t: T)(implicit f: Caller[T]) = f(t)

That said, your type class will probably want to look like:

 trait Caller[T]{
   def apply(t: T)
 }

wherein you place the actual things in scope and use the order of resolution to find the final Caller[Any] so that every else takes precedence. So I'd have it be done like this:

 object Wrap{
   implicit val xCal = new Caller[X]{
     def apply(x: X){ println("x called") }
   }
   implicit val yCal = new Caller[Y]{
     def apply(x: Y){ println("y called") }
   }
 }

 object `package`{
   implicit val anyCal = new Caller[Any]{
     def apply(t: Any){ println("any") }
   }
 }
like image 75
wheaties Avatar answered Mar 28 '23 03:03

wheaties