Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala implicit conversion from parent trait

The following code does not compile:

import scala.language.implicitConversions

trait Base {
  class Wrp[+T](val v: T) // wrapper / internal representation
}

trait BooleanOps extends Base {
  // implicit conversion
  implicit def lift2BooleanOpsCls(x: Boolean): BooleanOpsCls =
    new BooleanOpsCls(new Wrp[Boolean](x))
  class BooleanOpsCls(wx: Wrp[Boolean]) {
    def ||(wy: =>Wrp[Boolean]): Wrp[Boolean] = new Wrp[Boolean](wx.v || wy.v)
  }
}

trait MyExample extends BooleanOps {
  // test method
  def foo(): Wrp[Boolean] = {
    val ret: Wrp[Boolean] = false || new Wrp[Boolean](true)
    ret
  }
}

Output:

MyExample.scala:18: error: type mismatch;
 found   : MyExample.this.Wrp[Boolean]
 required: Boolean
        val ret: Wrp[Boolean] = false || new Wrp[Boolean](true)
                                         ^

But if I:

1) put the class Wrp outside of Base

or

2) move the body of BooleanOps to MyExample

everything compiles.

Why does not the original example work? If you have some insight in this behavior, help would be appreciated. Thank you.

like image 775
perovic Avatar asked Jan 22 '16 23:01

perovic


1 Answers

One issue is the call-by-name nature of the argument in the def ||(wy: =>Wrp[Boolean])
if you rewite it to def ||(wy: Wrp[Boolean]) it works

but I agree that it is weird that it works if you move around Wrp or BooleanOpsCls! Intended or bug of implicit resolution??

like image 100
cedricbastin Avatar answered Sep 17 '22 08:09

cedricbastin