I am new in Scala and I am referring book "Scala for Impatient - Second Edition".
I am working on a small code where I have created a class Fraction which as two Int fields num (number) and den(denominator). The class has a method * which performs multiplication of num and den and returns new Fraction instance.
Here, for understanding the working of implicit, I have created an object FractionConversions which helps with two implicit method intToFraction and fractionToDouble.
While testing the code in ImplicitConversionTester, I have imported the FractionConversions._ path, so both of the implicit methods are available to compiler.
Now, refer the code to make the picture more clear.
package OperatorOverloadingAndImplicitConversion class Fraction(n : Int, d : Int) { private val num = this.n private val den = this.d def *(other : Fraction) = new Fraction(num*other.num, den*other.den) override def toString: String = { s"Value of Fraction is : ${(num*0.1)/den}" } } object Fraction { def apply(n: Int, d: Int): Fraction = new Fraction(n, d) } object FractionConversions { implicit def fractionToDouble(f : Fraction): Double = { println("##### FractionConversions.fractionToDouble called ...") (f.num*0.1)/f.den } implicit def intToFraction(n : Int) : Fraction = { println("##### FractionConversions.intToFraction called ...") new Fraction(n,1) } } object ImplicitConversionTester extends App { import FractionConversions._ /* * CASE 1 : Here, "fractionToDouble" implicit is called. Why "intToFraction" was eligible but not called ? */ val a = 2 * Fraction(1,2) /* * CASE 2 : Works as expected. Here, number "2" is converted to Fraction using "intToFraction" implicit. */ val b = 2.den /* * CASE 3: Why again "intToFraction" but not "fractionToDouble" ? Why ? */ val c = Fraction(4,5) * 3 println(a) // output : 0.1 FractionConversions.fractionToDouble called println(b) // output : 1 FractionConversions.intToFraction called println(c) // output : Value of Fraction is : 0.24000000000000005. FractionConversions.intToFraction called } I have query in above code :
Case#1 : For statement
val a = 2 * Fraction(1,2), WhyfractionToDoubleimplicit is getting called here even thoughintToFractionis also eligible in this case ?case#3 : For statement
val c = Fraction(4,5) * 3, whyintToFractioncalled ? WhyfractionToDoublewas not used ?
Here, I tried to replicate the following scenario mentioned in the book, so above question arises. 
So, should We summarise that, the compiler avoids converting the left side operand and select the right side to convert if both of them are eligible for conversion ? For example, In case of (a*b), a is always ignored and b is converted to expected type even though a and b both are eligible for conversion ?
toFractiononIntandtoDoubleonFractiontoDoublebe an extension method if the OP owns the code ofFraction? Also,implicit class IntOps(n: Int) { def toFraction: Fraction = new Fraction(n,1) }is just a sugar forclass IntOps(n: Int) { def toFraction: Fraction = new Fraction(n,1) }; implicit def intToOps(n: Int): IntOps = new IntOps(n), so you actually can't stay absolutely away from implicit conversions.ifandwhileare implemented at the byte code as those, or that you can't stay away from loops becausemapis implemented using those, or that you can't stay away of machine code because everything will be executed by a CPU.scala.collection.JavaConversionsobject still existed but was deprecated: scala-lang.org/files/archive/api/2.12.13/scala/collection/…Fraction.*to accept doubles and another extension method*in theIntOpsclass to get the same API you wanted.