Hexx
Hexx

Reputation: 23

Implicit not resolved on high order function

I've got a function create is going to provide the parameter DSLContext of op: DSLContext => T :

def create[T](op: DSLContext => T)(implicit errorHandler: Throwable => Unit):Option[T] = {
  ...
  op(new DSLContext)
  ...
}

Then I pass the following function to create:

def query(implicit dsl:DSLContext)

And here is the call

create(query)

I got this compiler error:

could not find implicit value for parameter dsl: org.jooq.DSLContext [error] create (query)

I can resolve this issue this way : create {implicit dsl => query}

However i wonder why is the compiler unable to resolve the implicit parameter dsl as a given parameter ?

Upvotes: 2

Views: 111

Answers (1)

Gabriele Petronella
Gabriele Petronella

Reputation: 108151

The issue here is that when you pass a method where a function is expected the compiler needs to perform an eta-expansion to convert it.

In other words the method query needs to become a Function1[DSLContext, T].

However, the compiler needs to resolve the implicit parameter in order to be able to apply the eta-expansion. In your case there's no DSLContext in scope, so the compiler fails in doing so.

You can reproduce this behavior with a simpler example, here's a REPL session demonstrating it:

scala> def foo(implicit i: Int) = "hello"
foo: (implicit i: Int)String

scala> foo _
<console>:10: error: could not find implicit value for parameter i: Int
              foo _
              ^

scala> implicit val x = 5
x: Int = 5

scala> foo _
res3: scala.collection.immutable.WrappedString = hello

where _ manually triggers the eta-expansion.

For the record, this is described in the language reference, paragraph 6.26.2.

If the method takes only implicit parameters, implicit arguments are passed following the rules of §7.2.

Upvotes: 4

Related Questions