Currying

Currying in Scala transforms a function that takes more than one parameter into a function that takes multiple parameter lists. If you’re calling a function multiple times with the same set of arguments, you can reduce the noise and spice up the code by using currying.

Let’s see how Scala provides support for currying. Instead of writing a method that takes one parameter list with multiple parameters, write it with multiple parameter lists with one parameter each; you may have more than one parameter in each list as well. That is, instead of def foo(a: Int, b: Int, c: Int) = {}, write it as def foo(a: Int)(b: Int)(c: Int) {}. You can then call it as, for example, foo(1)(2)(3), foo(1){2}{3}, or even foo{1}{2}{3}.

Let’s examine what goes on when we define a method with multiple parameter lists. Take a look at the following interactive REPL session:

 
scala> def foo(a: Int)(b: Int)(c:Int) = {}
 
foo: (a: Int)(b: Int)(c: Int)Unit
 
 
scala> foo _
 
res0: Int => (Int => (Int => Unit)) = <function1>
 
 
scala> :quit

We first defined the function foo we discussed previously. Then we called foo _ to create a partially applied function—that is, a function with one or more parameters unbound. Partially applied functions are quite useful to create reusable convenience functions from other functions—we’ll explore that in more detail in Partially Applied Functions. We could’ve assigned the created partially applied function to a variable but did not care to in this example. We’re focused on the message from the REPL. It shows a series of three transformations. Each function in the chain takes one Int and returns a partially applied function. The last one, however, results in a Unit.

The creation of partially applied functions when we curry is Scala’s internal business. From a practical point of view, currying helps us to pass function values with syntactic sugar. Let’s use currying to rewrite the inject method from the previous section:

FunctionValuesAndClosures/Inject4.scala
 
def​ inject(arr: ​Array​[​Int​], initial: ​Int​)(operation: (​Int​, ​Int​) => ​Int​) = {
 
var​ carryOver = initial
 
arr.foreach(element => carryOver = operation(carryOver, element))
 
carryOver
 
}

The multiple parameter lists are the only difference between the two versions of the inject method. The first parameter list takes two parameters, and the second one takes only the function value.

Now we don’t have to send the function values as comma-separated parameters within parentheses anymore. We can use the much nicer curly bracket to call this method:

FunctionValuesAndClosures/Inject4.scala
 
val​ sum = inject(array, 0) { (carryOver, elem) => carryOver + elem }

We managed to move the function value out of the parentheses by using currying. Nice syntax sugar, but we can go further—the function value itself can be made more concise in cases where the parameters are used once, as you’ll see next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.183.221