I might be missing something but I came across a pattern that surprisingly doesn't work.
Here it is:
object A {
def bar(func: (Int, Int) => Int): Int = 2
def bar(func: Int => Int): Int = 3
def foo(func: Int => Int): Int = 4
}
def f(n: Int) : Int = n + 1
val g: Int => Int = f
A.foo(f) // works fine
A.bar(f) // doesn't work
A.bar(g) // but this works
The compiler ask me to explicitly apply the method f
in order to pass it (writing f _
) :Unapplied methods are only converted to functions when a function type is expected.
I don't get why the conversion is implicitly made when passing f
to A.foo
but not when passed to A.bar
. It might be related to the fact that bar
has two overloads but I'm not sure why ?
I'm using scalac with Scala 2.12.8.
The error message points you in the right direction: as a method, f
is not directly equivalent to a value of type Int => Int
, even though they are similar. In order to pass it as an argument, f
needs to be converted to a value, which is often, but not always done implicitly.
When you declare val g = f _
, or use A.bar(f _)
you explicitly convert the method to a value.
Because the bar
method is overloaded, the compiler is unsure which type you are converting f
to (is it Int => Int
or (Int,Int) => Int
?). To avoid any surprise, it asks you for an explicit conversion. You can also make it compile using A.bar(f: Int => Int)
, because that lifts the ambiguity by explicitly selecting one of the bar
definitions.
The compiler might attempt to reason about this because you're passing a Int => Int
and the implicit method->value lifting can only happen if you mean to give it to bar(Int => Int)
, but in this case it just doesn't. There might be a technical reason for this, like the compiler not attempting to combine overloads resolutions and implicit lifting because of combinatorial explosion. I would consider it a minor limitation of the compiler, which is easily circumvented by being more explicit. More explicit is often better!
As linked in the comments by @slouc, more technical details on this issue are available here.
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