Erlang高阶函数 #
一、高阶函数概述 #
高阶函数是可以接受函数作为参数或返回函数的函数。
1.1 函数作为一等公民 #
在Erlang中,函数可以:
- 赋值给变量
- 作为参数传递
- 作为返回值
- 存储在数据结构中
二、匿名函数 #
2.1 基本语法 #
erlang
-module(anonymous_basic).
-export([demo/0]).
demo() ->
Add = fun(A, B) -> A + B end,
Double = fun(X) -> X * 2 end,
io:format("Add(1, 2) = ~p~n", [Add(1, 2)]),
io:format("Double(5) = ~p~n", [Double(5)]),
ok.
2.2 多子句匿名函数 #
erlang
-module(anonymous_multi_clause).
-export([demo/0]).
demo() ->
Classify = fun
(0) -> zero;
(N) when N > 0 -> positive;
(N) when N < 0 -> negative
end,
io:format("Classify(0) = ~p~n", [Classify(0)]),
io:format("Classify(5) = ~p~n", [Classify(5)]),
io:format("Classify(-3) = ~p~n", [Classify(-3)]),
ok.
2.3 匿名函数调用 #
erlang
-module(anonymous_call).
-export([demo/0]).
demo() ->
Result = (fun(X) -> X * 2 end)(5),
io:format("Result = ~p~n", [Result]),
ok.
三、fun表达式 #
3.1 引用本地函数 #
erlang
-module(fun_local).
-export([demo/0]).
demo() ->
Double = fun double/1,
io:format("Double(5) = ~p~n", [Double(5)]),
ok.
double(X) -> X * 2.
3.2 引用模块函数 #
erlang
-module(fun_module).
-export([demo/0]).
demo() ->
Sqrt = fun math:sqrt/1,
Upper = fun string:uppercase/1,
io:format("Sqrt(16) = ~p~n", [Sqrt(16)]),
io:format("Upper(\"hello\") = ~p~n", [Upper("hello")]),
ok.
3.3 fun捕获 #
erlang
-module(fun_capture).
-export([create_adder/1]).
create_adder(N) ->
fun(X) -> X + N end.
四、闭包 #
4.1 闭包概念 #
闭包是捕获外部变量的函数:
erlang
-module(closure_basic).
-export([create_counter/0]).
create_counter() ->
Count = 0,
fun() ->
Count + 1
end.
4.2 可变状态闭包 #
erlang
-module(closure_state).
-export([create_counter/0]).
create_counter() ->
Counter = spawn(fun() -> loop(0) end),
fun() ->
Counter ! {increment, self()},
receive
{count, N} -> N
end
end.
loop(Count) ->
receive
{increment, From} ->
NewCount = Count + 1,
From ! {count, NewCount},
loop(NewCount)
end.
4.3 配置闭包 #
erlang
-module(closure_config).
-export([create_validator/1]).
create_validator(Rules) ->
fun(Data) ->
lists:all(fun(Rule) -> Rule(Data) end, Rules)
end.
五、函数作为参数 #
5.1 map函数 #
erlang
-module(map_function).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5],
Doubled = lists:map(fun(X) -> X * 2 end, Numbers),
Squared = lists:map(fun(X) -> X * X end, Numbers),
io:format("Doubled: ~p~n", [Doubled]),
io:format("Squared: ~p~n", [Squared]),
ok.
5.2 filter函数 #
erlang
-module(filter_function).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
Evens = lists:filter(fun(X) -> X rem 2 =:= 0 end, Numbers),
GreaterThan5 = lists:filter(fun(X) -> X > 5 end, Numbers),
io:format("Evens: ~p~n", [Evens]),
io:format("GreaterThan5: ~p~n", [GreaterThan5]),
ok.
5.3 fold函数 #
erlang
-module(fold_function).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5],
Sum = lists:foldl(fun(X, Acc) -> X + Acc end, 0, Numbers),
Product = lists:foldl(fun(X, Acc) -> X * Acc end, 1, Numbers),
Reversed = lists:foldl(fun(X, Acc) -> [X | Acc] end, [], Numbers),
io:format("Sum: ~p~n", [Sum]),
io:format("Product: ~p~n", [Product]),
io:format("Reversed: ~p~n", [Reversed]),
ok.
5.4 自定义高阶函数 #
erlang
-module(custom_higher_order).
-export([apply_twice/2, compose/2, pipeline/2]).
apply_twice(Fun, X) ->
Fun(Fun(X)).
compose(F1, F2) ->
fun(X) -> F1(F2(X)) end.
pipeline(Functions, Initial) ->
lists:foldl(fun(Fun, Acc) -> Fun(Acc) end, Initial, Functions).
六、函数作为返回值 #
6.1 工厂函数 #
erlang
-module(factory_function).
-export([create_adder/1, create_multiplier/1]).
create_adder(N) ->
fun(X) -> X + N end.
create_multiplier(N) ->
fun(X) -> X * N end.
6.2 函数组合 #
erlang
-module(function_composition).
-export([compose/2, demo/0]).
compose(F1, F2) ->
fun(X) -> F1(F2(X)) end.
demo() ->
Double = fun(X) -> X * 2 end,
AddOne = fun(X) -> X + 1 end,
DoubleThenAdd = compose(AddOne, Double),
AddThenDouble = compose(Double, AddOne),
io:format("DoubleThenAdd(5) = ~p~n", [DoubleThenAdd(5)]),
io:format("AddThenDouble(5) = ~p~n", [AddThenDouble(5)]),
ok.
6.3 柯里化 #
erlang
-module(currying).
-export([curry/1, demo/0]).
curry(Fun) when is_function(Fun, 2) ->
fun(A) ->
fun(B) ->
Fun(A, B)
end
end.
demo() ->
Add = fun(A, B) -> A + B end,
CurriedAdd = curry(Add),
Add5 = CurriedAdd(5),
io:format("Add5(3) = ~p~n", [Add5(3)]),
ok.
七、列表推导式 #
7.1 基本语法 #
erlang
-module(list_comprehension_basic).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5],
Doubled = [X * 2 || X <- Numbers],
Squared = [X * X || X <- Numbers],
io:format("Doubled: ~p~n", [Doubled]),
io:format("Squared: ~p~n", [Squared]),
ok.
7.2 带过滤条件 #
erlang
-module(list_comprehension_filter).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
Evens = [X || X <- Numbers, X rem 2 =:= 0],
GreaterThan5 = [X || X <- Numbers, X > 5],
EvenSquares = [X * X || X <- Numbers, X rem 2 =:= 0],
io:format("Evens: ~p~n", [Evens]),
io:format("GreaterThan5: ~p~n", [GreaterThan5]),
io:format("EvenSquares: ~p~n", [EvenSquares]),
ok.
7.3 多生成器 #
erlang
-module(multi_generator).
-export([demo/0]).
demo() ->
Pairs = [{X, Y} || X <- [1, 2, 3], Y <- [a, b]],
io:format("Pairs: ~p~n", [Pairs]),
ok.
7.4 嵌套列表处理 #
erlang
-module(nested_comprehension).
-export([demo/0]).
demo() ->
Nested = [[1, 2], [3, 4], [5, 6]],
Flattened = [X || SubList <- Nested, X <- SubList],
io:format("Flattened: ~p~n", [Flattened]),
ok.
7.5 二进制推导式 #
erlang
-module(binary_comprehension).
-export([demo/0]).
demo() ->
Binary = <<1, 2, 3, 4, 5>>,
List = [X || X <- Binary],
Doubled = << <<(X * 2)>> || X <- Binary >>,
io:format("List: ~p~n", [List]),
io:format("Doubled: ~p~n", [Doubled]),
ok.
八、常用高阶函数 #
8.1 lists模块 #
| 函数 | 说明 |
|---|---|
map/2 |
映射 |
filter/2 |
过滤 |
foldl/3 |
左折叠 |
foldr/3 |
右折叠 |
foreach/2 |
遍历执行 |
all/2 |
全部满足 |
any/2 |
任一满足 |
takewhile/2 |
取满足条件的元素 |
dropwhile/2 |
丢弃满足条件的元素 |
partition/2 |
分区 |
flatmap/2 |
平铺映射 |
zip/2 |
配对 |
zipwith/3 |
配对映射 |
8.2 使用示例 #
erlang
-module(lists_higher_order).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5],
AllPositive = lists:all(fun(X) -> X > 0 end, Numbers),
AnyGreaterThan3 = lists:any(fun(X) -> X > 3 end, Numbers),
TakeWhile = lists:takewhile(fun(X) -> X < 4 end, Numbers),
DropWhile = lists:dropwhile(fun(X) -> X < 4 end, Numbers),
FlatMap = lists:flatmap(fun(X) -> [X, X * 2] end, [1, 2, 3]),
Zip = lists:zip([a, b, c], [1, 2, 3]),
ZipWith = lists:zipwith(fun(X, Y) -> {X, Y} end, [a, b], [1, 2]),
io:format("AllPositive: ~p~n", [AllPositive]),
io:format("AnyGreaterThan3: ~p~n", [AnyGreaterThan3]),
io:format("TakeWhile: ~p~n", [TakeWhile]),
io:format("DropWhile: ~p~n", [DropWhile]),
io:format("FlatMap: ~p~n", [FlatMap]),
io:format("Zip: ~p~n", [Zip]),
io:format("ZipWith: ~p~n", [ZipWith]),
ok.
九、实际应用 #
9.1 数据处理管道 #
erlang
-module(data_pipeline).
-export([process/1]).
process(Data) ->
Pipeline = [
fun validate/1,
fun transform/1,
fun enrich/1
],
lists:foldl(fun(Fun, {ok, Acc}) -> Fun(Acc); (_, Error) -> Error end,
{ok, Data}, Pipeline).
validate(Data) -> {ok, Data}.
transform(Data) -> {ok, {transformed, Data}}.
enrich(Data) -> {ok, {enriched, Data}}.
9.2 事件处理 #
erlang
-module(event_handler).
-export([handle/2]).
handle(Event, Handlers) ->
lists:foreach(fun(Handler) -> Handler(Event) end, Handlers).
9.3 配置处理 #
erlang
-module(config_processor).
-export([apply_defaults/2]).
apply_defaults(Config, Defaults) ->
lists:foldl(
fun({Key, Default}, Acc) ->
case maps:is_key(Key, Acc) of
true -> Acc;
false -> Acc#{Key => Default}
end
end,
Config,
Defaults
).
十、总结 #
本章学习了:
- 匿名函数
- fun表达式
- 闭包
- 函数作为参数
- 函数作为返回值
- 列表推导式
- 常用高阶函数
- 实际应用
准备好学习模块了吗?让我们进入下一章。
最后更新:2026-03-27