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