Why is the following (toy) sample compiled in Scala without any problem, and what is the rule used for deciding which implicit conversion to chose?
object test1 {
class MyInt(val v: Int) {
def +(other: MyInt) = new MyInt(v + other.v)
override def toString = v.toString
}
class MyIntMod10(vparam: Int) {
val v = vparam % 10;
def +(other: MyIntMod10) = new MyIntMod10(v + other.v)
override def toString = v.toString
}
val a = new MyInt(7); //> a : test1.MyInt = 7
val b = new MyIntMod10(7); //> b : test1.MyIntMod10 = 7
implicit def toIntMod10(x: MyInt) = new MyIntMod10(x.v)
//> toIntMod10: (a: test1.MyInt)test1.MyIntMod10
val c1 = a + b //> c1 : test1.MyIntMod10 = 4
val c2 = b + a //> c2 : test1.MyIntMod10 = 4
implicit def toInt(x: MyIntMod10) = new MyInt(x.v) //> toInt: (b: test1.MyIntMod10)test1.MyInt
val c3 = a + b //> c3 : test1.MyInt = 14
val c4 = b + a //> c4 : test1.MyIntMod10 = 4
}
I expected the two last lines to produce compile-time error because of ambiguity, but they don't. (As far as I know, the fact that the values of c1 and c3 are different, directly shows the ambiguity in calculating c3! please correct me if I'm wrong.)
I know that in current versions of Scala, some ambiguous implicit calls are resolved by the compiler, but I can't see how the given sample code is one of those special cases!