In Scala you can do things like:
def foo(implicit v: Int) = println(v);
def h(x: Int) = { implicit val i: Int = x; foo }
h(42)
> 42
h
call gets foo
reference as a closure.
It wouldn't be strange to try passing foo
to h
as a parameter:
def g(x: Int)(f: Int => Unit) = { implicit val i: Int = x; f }
But it wouldn't work:
g(1)(foo)
> error: could not find implicit value for parameter v: Int
What I think it's happening is that foo
gets called as an evaluation of the actual parameter. Is that right?
When passed a function with a normal parameter list (not implicit), the function is not being evaluated:
def foo2(v: Int) = println("Foo2")
g(1)(foo2)
> Int => Unit = <function1>
This is an expected result and foo2
evaluation is not tried as a evaluation of an actual parameter.
Why is foo
evaluated as an actual parameter when no implicit values are available to do so?
Same occurs with assignation:
val fooref: Int => Unit = foo
> error: could not find implicit value for parameter v: Int
It is like since Int => Unit
doesn't match with a function where the Int
parameter is marked as implicit, the compiler discard it as a valid actual parameter and therefore tries to evaluate it. Not finding a declared implicit value to fulfill the call.
If that is the case, what whould be the way of expressing the type of a function with implicit parameters?
Unfortunately, functions cannot have implicit parameters - only methods can.
In the expression g(1)(foo)
, foo
is converted from a method to a function (also known as eta-expansion). And section 6.26.2 of the Scala Specification states that implicit arguments are applied before eta-expansion.
See this ticket: implicit methods behave suboptimally when used non-implicitly
The type of the f
parameter to function g
is Function1[Int, Unit]
. Function1[A, B]
is a trait with the single method apply(a: A): B
, where the a
is not implicit. Hence, you cannot create an instance of Function1[Int, Unit]
from foo
- it wouldn't have the right signature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With