- 12.1 Functions as Values
- 12.2 Anonymous Functions
- 12.3 Parameters That Are Functions
- 12.4 Parameter Inference
- 12.5 Useful Higher-Order Functions
- 12.6 Closures
- 12.7 Interoperability with Lambda Expressions
- 12.8 Currying
- 12.9 Methods for Composing, Currying, and Tupling
- 12.10 Control Abstractions
- 12.11 Nonlocal Returns
- Exercises
12.5 Useful Higher-Order Functions
A good way of becoming comfortable with higher-order functions is to practice with some common (and obviously useful) methods in the Scala collections library that take function parameters.
You have seen map, which applies a function to all elements of a collection and returns the result. Here is a quick way of producing a collection containing 0.1, 0.2,..., 0.9:
(1 to 9).map(0.1 * _)
Try this to print a triangle:
(1 to 9).map("*" * _).foreach(println _)
The result is
* ** *** **** ***** ****** ******* ******** *********
Here, we also use foreach, which is like map except that its function doesn’t return a value. The foreach method simply applies the function to each argument.
The filter method yields all elements that match a particular condition. For example, here’s how to get only the even numbers in a sequence:
(1 to 9).filter(_ % 2 == 0) // 2, 4, 6, 8
Of course, that’s not the most efficient way of getting this result .
The reduceLeft method takes a binary function—that is, a function with two parameters—and applies it to all elements of a sequence, going from left to right. For example,
(1 to 9).reduceLeft(_ * _)
is
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9
or, strictly speaking,
(...((1 * 2) * 3) * ... * 9)
Note the compact form of the multiplication function: _ * _. Each underscore denotes a separate parameter.
You also need a binary function for sorting. For example,
"Mary had a little lamb".split(" ").sortWith(_.length < _.length)
yields an array that is sorted by increasing length: Array("a", "had", "Mary", "lamb", "little").