Higher-Order Functions & Funs

10.1 Anonymous functions

Double = fun(X) -> X * 2 end,
Double(5),                                   % 10

Add = fun(A, B) -> A + B end,
Add(2, 3).

10.2 Multi-clause funs

Handle = fun({ok, V}) -> V;
            ({error, _}) -> default
         end.

10.3 Closures

make_adder(N) -> fun(X) -> X + N end.
Add5 = make_adder(5), Add5(10).        % 15

10.4 References to named functions

F = fun lists:reverse/1,
F([1, 2, 3]),
G = fun local_fun/1.                   % local function reference
lists:map(fun erlang:abs/1, [-1, 2]).

10.5 Named (recursive) funs (OTP 17+)

Fact = fun Self(0) -> 1; Self(N) -> N * Self(N - 1) end,
Fact(5).    % 120

10.6 Common higher-order functions

lists:map(fun(X) -> X * X end, [1, 2, 3]),             % [1,4,9]
lists:filter(fun(X) -> X rem 2 =:= 0 end, [1,2,3,4]),   % [2,4]
lists:foldl(fun(X, Acc) -> X + Acc end, 0, [1,2,3]),    % 6
lists:foldr(fun(X, Acc) -> [X | Acc] end, [], [1,2]),
lists:foreach(fun(X) -> io:format("~p~n", [X]) end, [a, b]),
lists:any(fun is_atom/1, [1, a]), lists:all(fun is_integer/1, [1, 2]),
lists:filtermap(fun(X) when X > 1 -> {true, X * 10}; (_) -> false end, [1, 2, 3]),
lists:flatmap(fun(X) -> [X, X] end, [1, 2]),
lists:mapfoldl(fun(X, Acc) -> {X * 2, Acc + X} end, 0, [1, 2, 3]).

10.7 Function composition

compose(F, G) -> fun(X) -> F(G(X)) end.
pipe(Value, Funs) -> lists:foldl(fun(F, Acc) -> F(Acc) end, Value, Funs).

pipe("  Hello ", [fun string:trim/1, fun string:uppercase/1]).   % "HELLO"