- 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.3 Parameters That Are Functions
In this section, you will see how to implement a function whose parameter is another function. Here is an example:
def valueAtOneQuarter(f: (Double) => Double) = f(0.25)
Note that the parameter can be any function receiving and returning a Double. The valueAtOneQuarter function computes the value of that function at 0.25.
For example,
valueAtOneQuarter(ceil) // 1.0 valueAtOneQuarter(sqrt) // 0.5 (because 0.5 × 0.5 = 0.25)
What is the type of valueAtOneQuarter? It is a function with one parameter, so its type is written as
(parameterType) => resultType
The resultType is clearly Double, and the parameterType is already given in the function header as (Double) => Double. Therefore, the type of valueAtOneQuarter is
((Double) => Double) => Double
Since valueAtOneQuarter is a function that receives a function, it is called a higher-order function.
A higher-order function can also produce a function. Here is a simple example:
def mulBy(factor : Double) = (x : Double) => factor * x
For example, mulBy(3) returns the function (x : Double) => 3 * x which you have seen in the preceding section. The power of mulBy is that it can deliver functions that multiply by any amount:
val quintuple = mulBy(5) quintuple(20) // 100
The mulBy function has a parameter of type Double, and it returns a function of type (Double) => Double. Therefore, its type is
(Double) => ((Double) => Double)
When written without parentheses, the type is
Double => Double => Double