I have this set of overloaded functions:
case class A[T](t: T)
object C {
def dump(a: A[String], s: String) = ....
def dump(a: A[Int], s: Int) = ....
def dump(a: A[Double], s: Double) = ....
}
and have this generic method:
class B {
def dump[T](a: A[T], t: T) = C.dump(a, t)
}
It doesn't compile, because the Scala compiler gets confused with the different overloads. What is the right way of doing it?
edit: The problem with your implementation is, that at compile time it does not know which version of C.dump
it should use, because it only know that there is some type T
, but it can't possibly know what type it will hold when the method is actually being used.
You can solve this using ad-hoc polymorphism:
trait Dumper[A] {
def dump(a: A): Unit
}
case class A[T](t: T)
object A {
implicit object AStringDumper extends Dumper[A[String]] {
def dump(a: A[String]) = println(s"String: $a")
}
implicit object ADoubleDumper extends Dumper[A[Double]] {
def dump(a: A[Double]) = println(s"Double: $a")
}
}
object C {
def dump[A](a: A)(implicit dumper: Dumper[A]) = dumper.dump(a)
}
The compiler will try to find an instance of Dumper[A]
when you call C.dump
. If it can't find one, it will not compile:
scala> C.dump(A("foo"))
String: A(foo)
scala> C.dump(A(1.2))
Double: A(1.2)
scala> C.dump(A(1))
<console>:17: error: could not find implicit value for parameter dumper: Dumper[A[Int]]
C.dump(A(1))
Based on @drexin answer by using ad-hoc polymorphism, I just slightly change to use the signature of the question to make it a little bit more clear.
def dump[T](a: A[T], t: T) = C.dump(a, t)
case class A[T](t: T)
trait Dumper[T] {
def dump(a: A[T], t: T): Unit
}
class B {
def dump[T](a: A[T], t: T)(implicit dumper: Dumper[T]) = dumper.dump(a, t)
}
implicit val IntDummper = new Dumper[Int] {
override def dump(a: A[Int], t: Int): Unit = {
println("int dummper processing it")
}
}
implicit val StringDummper = new Dumper[String] {
override def dump(a: A[String], t: String): Unit = {
println("string dummper processing it")
}
}
val result = new B
result.dump(A("3"), "3") //string dummper processing it
result.dump(A(3), 3) //int dummper processing it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With