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.

+3


source to share


2 answers


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)

      

+2


source


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).

+1


source







All Articles