Dart Higher-Order Functions
A higher-order function is a function that takes a function as an input or returns a function as a result. It treats a function as a value that can be passed around like any other value.
Running a function twice
applyTwice receives a function and a starting value. The two calls use different passed functions and print different results.
int applyTwice(int Function(int) f, int x) {
return f(f(x));
}
void main() {
print(applyTwice((n) => n + 3, 4));
print(applyTwice((n) => n * 2, 5));
}Composing through a wrapper
compose holds the order of the two steps in one place. Adding 1 first and tripling second turns 4 into 15.
int compose(int Function(int) first, int Function(int) second, int value) {
return second(first(value));
}
void main() {
var result = compose((n) => n + 1, (n) => n * 3, 4);
print(result);
}A default function value
report falls back to keepSame when no function is passed. Passing addTen for the second call changes the printed value.
int keepSame(int n) {
return n;
}
int addTen(int n) {
return n + 10;
}
void report(int value, [int Function(int) change = keepSame]) {
print(change(value));
}
void main() {
report(7);
report(7, addTen);
}A loop helper that transforms a list
transformAll walks the list itself and builds a new list with the passed closure. The same helper doubles the prices in one call and raises them by 1 in the next.
List<int> transformAll(List<int> items, int Function(int) change) {
var result = <int>[];
for (var item in items) {
result.add(change(item));
}
return result;
}
void main() {
var prices = [2, 5, 8];
print(transformAll(prices, (n) => n * 2));
print(transformAll(prices, (n) => n + 1));
}Example
int calculate(int a, int b, int Function(int, int) op) {
return op(a, b);
}
void main() {
print(calculate(6, 3, (x, y) => x + y));
print(calculate(6, 3, (x, y) => x * y));
print(calculate(6, 3, (x, y) => x - y));
}Key points
- A function parameter has a function type that states its inputs and its result.
- applyTwice runs its function input on a value, then runs it again on the result.
- Composing means feeding the result of one function into another function.
- A small wrapper function can hold a composition and give it a name.
- A function parameter can declare a default function value for callers that pass nothing.
- A hand-written helper can take a closure and apply it to each item in a list.
In this example, calculate keeps the two numbers fixed and swaps only the operation. The three closures add, multiply, and subtract the same pair. The prints show 9, 18, and 3.
Try it Yourself
Edit the code, then press Run.
Running is simulated · DartPad
Exercise
What does applyTwice((n) => n + 1, 10) print, using the applyTwice from this lesson?