Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Scala has a restriction on automatic conversions to add a method, which is that it won't apply more than one conversion in trying to find methods. For example:</p> <pre><code>class A(val n: Int) class B(val m: Int, val n: Int) class C(val m: Int, val n: Int, val o: Int) { def total = m + n + o } // This demonstrates implicit conversion chaining restrictions object T1 { // to make it easy to test on REPL implicit def toA(n: Int): A = new A(n) implicit def aToB(a: A): B = new B(a.n, a.n) implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n) // won't work println(5.total) println(new A(5).total) // works println(new B(5, 5).total) println(new C(5, 5, 10).total) } </code></pre> <p><strong>EDIT: View bounds ('&lt;%') are deprecated since Scala 2.11 <a href="https://issues.scala-lang.org/browse/SI-7629" rel="noreferrer">https://issues.scala-lang.org/browse/SI-7629</a></strong> (You can use type classes instead)</p> <p>However, if an implicit definition requires an implicit parameter itself(View bound), Scala <em>will</em> look for additional implicit values for as long as needed. Continue from the last example:</p> <pre><code>// def m[A &lt;% B](m: A) is the same thing as // def m[A](m: A)(implicit ev: A =&gt; B) object T2 { implicit def toA(n: Int): A = new A(n) implicit def aToB[A1 &lt;% A](a: A1): B = new B(a.n, a.n) implicit def bToC[B1 &lt;% B](b: B1): C = new C(b.m, b.n, b.m + b.n) // works println(5.total) println(new A(5).total) println(new B(5, 5).total) println(new C(5, 5, 10).total) } </code></pre> <p>"Magic!", you might say. Not so. Here is how the compiler would translate each one:</p> <pre><code>object T1Translated { implicit def toA(n: Int): A = new A(n) implicit def aToB(a: A): B = new B(a.n, a.n) implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n) // Scala won't do this println(bToC(aToB(toA(5))).total) println(bToC(aToB(new A(5))).total) // Just this println(bToC(new B(5, 5)).total) // No implicits required println(new C(5, 5, 10).total) } object T2Translated { implicit def toA(n: Int): A = new A(n) implicit def aToB[A1 &lt;% A](a: A1): B = new B(a.n, a.n) implicit def bToC[B1 &lt;% B](b: B1): C = new C(b.m, b.n, b.m + b.n) // Scala does this println(bToC(5)(x =&gt; aToB(x)(y =&gt; toA(y))).total) println(bToC(new A(5))(x =&gt; aToB(x)(identity)).total) println(bToC(new B(5, 5))(identity).total) // no implicits required println(new C(5, 5, 10).total) } </code></pre> <p>So, while <code>bToC</code> is being used as an implicit conversion, <code>aToB</code> and <code>toA</code> are being passed as <em>implicit parameters</em>, instead of being chained as implicit conversions.</p> <p><strong>EDIT</strong></p> <p>Related question of interest:</p> <ul> <li><a href="https://stackoverflow.com/q/5598085/53013">A discussion on types, origin and precedence of implicits</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload