I can find a document specifying the Scala rule about coercion of functions passed to higher-order function (... the method decorator.layout is coerced automatically to a value of type Int => String).
If I defined the following.
object Foo {
def bar[T1, R](f: T1 => R): T1 => R = f
}
def fn1(s: String): Int = 1
Then in the REPL I can do:
scala> Foo.bar({ s: String => 1 })
res: String => Int = <function1>
scala> Foo.bar(fn1)
res: String => Int = <function1>
Everything is fine and clear up to there, but if I update Foo
:
object Foo {
def bar[T1, R](f: T1 => R): T1 => R = f
// NEW
def bar[T1, T2, R](f: Function2[T1, T2, R]): Tuple2[T1, T2] => R = { case (c1, c2) => f(c1, c2) }
}
Then in the REPL:
scala> Foo.bar({ s: String => 1 })
res: String => Int = <function1>
scala> Foo.bar(fn1)
<console>:12: error: missing arguments for method fn1;
follow this method with `_' if you want to treat it as a partially applied function
Foo.bar(fn1)
Some this call bar(fn1)
which was working with the first version of Foo
need to be updated in the following way.
scala> Foo.bar(fn1 _)
res: String => Int = <function1>
That's fine but I would like to make sure which rules the Scala compiler follows about that, when the syntax higherFn(fn)
can be used and when it cannot (and that syntax higherFn(fn _)
is required).
I guess the polymorphism of the higher-order function has something to do with that...