I have read other same question here, however the case is too specific for certain built-in class. I want to ask for simple case here and hoping for general answer.
So I have this code:
object ScalaApp {
case class Point(x: Int, y: Int);
case class Rational(n: Int, d: Int) {
def \(i: Int): List[Int] = n :: d:: i :: Nil
}
case class MyObject(x: Int, y: Int, z: Int) {
def \(i: Int): List[Int] = x :: y:: i :: Nil
}
implicit def pointToRational(p: Point): Rational = Rational(p.x + 1, p.y * 2)
implicit def pointToMyObject(p: Point): MyObject = MyObject(p.x, p.y, p.x+p.y)
def main(args: Array[String]) {
val p = Point(5, 7)
val result = p \ 6 // compile error here
}
}
We can see the error happened when p
is applied to \
method then the implicit conversion is triggered. Scala compiler will try to look for any imported or local class that has def \(i: Int)
method defined. If found, then it will try to look for any implicit conversion method that take Point
type and return the type of object that has def \(i: Int)
method signature.
It happened there are two class that has def \
method here: Rational
and MyObject
, and there are two implicit methods too: pointToRational
and pointToMyObject
for those two classes.
However since both Rational
and MyObject
has def \
defined, hence the ambiguous compile error occured because it can't decide which one should be taken.
Error:(30, 22) type mismatch;
found : p.type (with underlying type ScalaApp.Point)
required: ?{def \(x$1: ? >: Int(6)): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method pointToRational in object ScalaApp of type (p: ScalaApp.Point)ScalaApp.Rational
and method pointToObj in object ScalaApp of type (p: ScalaApp.Point)ScalaApp.MyObject
are possible conversion functions from p.type to ?{def \(x$1: ? >: Int(6)): ?}
val result = p \ 6
^
So my question, is there a way to resolve the ambiguous implicit error but still retaining the two def \
methods or without removing one of implicit conversion method?