Reputation: 33
When I create a partial function, why can't I immediately invoke it?
Both res6 and res8 are the same type (function1) so I'm not sure how come res7 works (immediately invoking it) and what would be res9 fails
scala> ((x: Int) => x + 1)
res6: Int => Int = <function1>
scala> ((x: Int) => x + 1)(1)
res7: Int = 2
scala> def adder(a: Int, b: Int) = a + b
adder: (a: Int, b: Int)Int
scala> adder(1, _: Int)
res8: Int => Int = <function1>
scala> adder(1, _: Int)(1)
<console>:12: error: Int does not take parameters
adder(1, _: Int)(1)
^
scala> (adder(1, _: Int))(1)
res10: Int = 2
Upvotes: 2
Views: 64
Reputation: 14217
adder(1, _: Int)
This is caused by scala compiler will expand it to:
((x: Int) => adder(1, x)(1))
and this is caused by the compiler can't infer the wildcard's context, like:
_ + _
scala> _ + _
<console>:17: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
_ + _
^
<console>:17: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
_ + _
so you can do it with context bounds, as your way:
(adder(1, _: Int))(1)
it will be expanded like:
((x: Int) => adder(1, x))(1)
Upvotes: 1
Reputation: 16412
I think you've just found one of the little Scala compiler quirks.
I don't know how this case is implemented exactly in the parser, but from the looks of it Scala thinks you are invoking a function with multiple parameter lists (of the form f(...)(...)
). Thus you need to explicitly surround the partially applied function with brackets here, so that compiler could disambiguate between f()()
and f(_)()
forms. In res8
you don't have any parameters following the function, so there is no ambiguity. Otherwise, Scala would require you to follow the function with underscore if you ommit parameter list: f _
or f() _
.
You can still immediately apply that function as you show in res10
.
Upvotes: 1