Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala implicit parameters with defaults defined in the companion object

According to the Scala Spec (2.8), for an implicit to be found it must be defined in local scope, inherited scope, or in a companion object. Given that, it seems to me that the following code should work without an explicit import of the contents of the companion object. I see this used in the Scala library source (eg. CanBuildFrom). It also seems that I should be able to call XX.foo() from outside the definition of the XX class and have my implicit parameter from the companion class used. What am I missing?

object XX {
   implicit def XYZ[T]: (T) => Unit = null
}

class XX {
  // import XX._     // Works with this line uncommented...
  def foo(s: String)(implicit f: (String) => Unit): Unit = {
    if (f == null)
      println("Just: " + s)
    else
      f(s)
  }

  def bar {
    foo("abc"){ s => println("Func: " + s)}
    foo("xyz")  // <-- Compile error here: could not find implicit value for parameter f
  }
}
like image 603
sellmerfud Avatar asked Jan 20 '11 16:01

sellmerfud


1 Answers

I always interpreted the spec to mean that the implicit can be defined in the companion object of the implicit parameter, not the class containing the definition. Something like this:

object ZZ {
   implicit val xyz: ZZ = new ZZ()
}
class ZZ {
  def bar: (String) => Unit = null
}

class XX {
  def foo(s: String)(implicit f: ZZ): Unit = {
    if (f.bar == null)
      println("Just: " + s)
    else
      f.bar(s)
  }

  def bar {
    foo("xyz")
  }
}

It seems clear in Section 7.2 of the spec:

The actual arguments that are eligible to be passed to an implicit parameter of type T fall into two categories. First, eligible are all identifiers x that can be accessed at the point of the method call without a prefix and that denote an implicit definition (§7.1) or an implicit parameter. An eligible identifiermay thus be a local name, or a member of an enclosing template, or it may be have been made accessible without a prefix through an import clause (§4.7). If there are no eligible identifiers under this rule, then, second, eligible are also all implicit members of some object that belongs to the implicit scope of the implicit parameter’s type, T.

Can you quote the part that indicates the companion object of the containing class of the definition?

like image 120
Mitch Blevins Avatar answered Sep 21 '22 16:09

Mitch Blevins