fsauer
fsauer

Reputation: 23

apply function with implicit parameter requires explicit argument

I can't figure out why this does not work:

case class Expression extends Node[Doube] {

   def apply(implicit symbolTable: Map[String,Double]) = value
}

note that value is defined in Node, also with an implicit symbol table argument.

When I try to invoke it like so:

implicit val symbolTable = Map("a"->1, "b"->2)
//and x is an Expression, then:

x() // does not compile (can't find implicit) but 
x(symbolTable) // works fine

and strangely:

x.value // works fine too

if I write apply like so:

def apply()(implicit symbolTable: Map[String,Double]) 

it works, but I don't understand why I need to do that....

Any pointers?

Upvotes: 0

Views: 2448

Answers (1)

som-snytt
som-snytt

Reputation: 39577

The spec distinguishes value conversions from method conversions.

x is a value. For your example with two param lists, x() is a method type with one param list, the implicit one, which is supplied implicitly.

For your original example, with one implicit param list, x() fails to supply a required arg. (Not "implicit not found.")

scala> def f(implicit s: String) = 42
f: (implicit s: String)Int

scala> f
<console>:9: error: could not find implicit value for parameter s: String
              f
              ^

scala> f()
<console>:9: error: not enough arguments for method f: (implicit s: String)Int.
Unspecified value parameter s.
              f()
               ^

For the implicits to be supplied, you must not supply the param list.

For your strange x.value, obviously value is a method with one implicit param list.

More:

scala> object x { def apply(implicit s: String) = 42 }
defined object x

scala> x.apply
<console>:9: error: could not find implicit value for parameter s: String
              x.apply
                ^

scala> implicit val s: String = "hi"
s: String = hi

scala> x.apply
res1: Int = 42

scala> x()
<console>:10: error: not enough arguments for method apply: (implicit s: String)Int in object x.
Unspecified value parameter s.
              x()
               ^

When you write x.apply as above, it will either supply parens to turn it into an application, supplying implicit args, or try to turn it into a function if the context wants that.

Upvotes: 1

Related Questions