Wednesday, April 21, 2010

Companion Object Implicits

When a method requires an implicit there are several ways that the implicit is resolved. One way is to search for an implicit definition in the companion object of the required type. For example: def x(implicit m:MyClass) parameter m will search local scope, class hierarchy and the MyClass companion object for an implicit val or def. (More on implicit resolution later).

To demonstrate the method put the following code block into a file and run the script:
  1. class X(val i:Int) {
  2.   def add(implicit x:X)=println(x.i+i)
  3. }
  4. object X {
  5.   implicit def xx = new X(3)
  6. }
  7. // implicit is obtained from companion object of X
  8. new X(3).add
  9. val other = new {
  10.   def print(implicit x:X)=println(x.i)
  11. }
  12. // implicit is obtained from companion object of X
  13. other.print
  14. implicit def x = new X(32)
  15. // implicit is obtained local scope
  16. other.print

Running: scala impl.scala should produce:
6
3
32

3 comments:

  1. Speaking of which, why does the following not work?

    class A(i: Int)
    object A {implicit def int2A(i: Int) = new A(i) }
    val a: A = 2

    The implicit conversion is defined in the companion object of the expected type. Which part do I not get?

    It does of course work if I "import A._", but I'm still looking for a way around that.

    ReplyDelete
  2. You are confusing implicit parameter resolution with implicit object conversion. Implicit object conversion is potentially dangerous so they normally have to be imported explicitly into scope.

    Caveats to that is implicit object conversions defined in superclasses and (I am pretty sure) in package objects are automatically in scope.

    I will address this soon.

    ReplyDelete
  3. Dear Jesse,

    I put the implicit conversion into a package object now and that indeed did the trick. Thanks for the hint!

    ReplyDelete