Why call currying function with underscored incomplete arguments
According to ScalaByExample:
The definition of a card function def f (args1) ... (argsn) = E, where n> 1 expands to
def f (args1) ... (argsn-1) = {def g (argsn) = E; g}
Or, in short, using an anonymous function:
def f (args1) ... (argsn-1) = (argsn) => E
Direct version:
def f(x: Int): Int => Int = {
y: Int => x * y
} //> f: (x: Int)Int => Int
def f1 = f(10) //> f1: => Int => Int
f1(5)
Current version:
def g(x: Int)(y: Int) = {
x * y
} //> g: (x: Int)(y: Int)Int
def g1 = g(10) _ //> g1: => Int => Int
g1(5)
The question is why fory needed to underline line # 5 in the second code snippet.
source to share
You can find an explanation in the book by Martin Odersky: http://www.artima.com/pins1ed/functions-and-closures.html (search for "Why trailing underscore").
In short, this is because Scala is closer to Java in many ways, and not to functional languages ββwhere it is not required. This will help you find out compile-time errors if you forget a missing argument.
If no underscore was required, the following code will compile:
println(g(10))
And this check helps prevent such errors.
However, there are cases where such calls are obvious and no underscore is required:
def g(x: Int)(y: Int) = {
x * y
}
def d(f: Int => Int) {
f(5)
}
d(g(10)) // No need to write d(g(2) _)
// Or any other way you can specify the correct type
val p: Int => Int = g(10)
source to share
Something to note: in Scala, def
there are methods, not functions, at least not directly. Methods are converted to functions by the compiler each time a method is used where the function is required, but strictly speaking, the function would instead be created with val
:
val curry = (x: Int) => (y: Int) => x * y
This allows arguments to be applied one at a time without adding a trailing underscore. It functions identically to the code in your first snippet, but because it uses val
and not def
, curry
it cannot be written as
val curry(x: Int) = (y: Int) => x * y //Won't compile
So when you want to write a function that behaves the way you want to work with the map, write it like in my first snippet. You can save chain parameters =>
as many times as you like (up to technical limitations, but luck hits them).
source to share