This produces an anonymous function, as you would expect (f is a function with three arguments):
f(_, _, _)
What I don't understand is why this doesn't compile, instead giving a "missing parameter type" error:
f(_, _, 27)
Instead, I need to specify the types of the underscores explicitly. Shouldn't Scala be able to infer them given that it knows what the function f's parameter types are?
The Partially applied functions are the functions which are not applied on all the arguments defined by the stated function i.e, while invoking a function, we can supply some of the arguments and the left arguments are supplied when required.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
Scala - Functions with Named Arguments Named arguments allow you to pass arguments to a function in a different order. The syntax is simply that each argument is preceded by a parameter name and an equals sign. Try the following program, it is a simple example to show the functions with named arguments.
References below are to the Scala Language Specification
Consider the following method:
def foo(a: Int, b: Int) = 0
Eta Expansion can convert this to a value of type (Int, Int) => Int
. This expansion is invoked if:
a) _
is used in place of the argument list (Method Value (§6.7))
val f = foo _
b) the argument list is omitted, and expected type of expression is a function type (§6.25.2):
val f: (Int, Int) => Int = foo
c) each of the arguments is _
(a special case of the 'Placeholder Syntax for Anonymous Functions' (§6.23))
val f = foo(_, _)
The expression, foo(_, 1)
doesn't qualify for Eta Expansion; it just expands to (a) => foo(a, 1)
(§6.23). Regular type inference doesn't attempt to figure out that a: Int
.
If you are thinking about partial application, I thought that this was only possible with multiple parameter lists (whereas you only have one):
def plus(x: Int)(y: Int) = x + y //x and y in different parameter lists val plus10 = plus(10) _ //_ indicates partial application println(plus10(2)) //prints 12
Your example is interesting though as I was completely unaware of the syntax you describe and it appears you can have partial application with a single parameter list:
scala> def plus2(x: Int, y: Int) = x + y plus2: (x: Int,y: Int)Int scala> val anon = plus2(_,_) anon: (Int, Int) => Int = <function2> scala> anon(3, 4) res1: Int = 7
So the compiler can clearly infer the type Int
!
scala> val anon2 = plus2(20,_) <console>:5: error: missing parameter type for expanded function ((x$1) => plus2(20, x$1)) val anon2 = plus2(20,_) ^
Hmmm, strange! I don't seem to be able to do partial application with a single parameter list. But then if I declare the type of the second parameter, I can have partial application!
scala> val anon2 = plus2(20,_: Int) anon2: (Int) => Int = <function1> scala> anon2(24) res2: Int = 44
EDIT - one thing I would observe is that it seems like the following two shortenings are equivalent, in which case it's a bit more obvious that this is not a "partial application" but more like a "function pointer"
val anon1 = plus2(_,_) val anon2 = plus2 _
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