Erlang顺序型编程

时间:2022-06-01 17:55:39

模块

%% 模块代码
-module(geometry).
-export([area/1]).
area({rectangle, Width, Ht}) -> Width * Ht;
area({circle, R}) -> 3.14 * R * R.

%% 编译模块
1> c(geometry, debug_info).   %% 添加调试信息
1> c(geometry).
{ok,geometry}
2> geometry:area({rectangle, 10, 5}).
50
3> geometry:area({circle, 1.68}).
8.862335999999999

扩展这个程序

-module(geometry).
-export([area/1]).
area({rectangle, Width, Ht}) -> Width * Ht;
area({circle, R}) -> 3.14 * R * R;
area({square, X}) -> X * X.

购物系统-进阶

%% 返回单价
-module(shop).
-export([cost/1]).
cost(oranges) -> 5;
cost(newspaper) -> 8;
cost(apples) -> 2;
cost(pears) -> 9;
cost(milk) -> 7.

%% 计算总价
-module(settle).
-export([total/1]).
total([{What,N}|T])->  shop:cost(What) * N + total(T);
total([]) -> 0.

%% 调用
1> BuyList = [{oranges,4},{newspaper,1},{apples,1},{pears,6},{milk,3}].
[{oranges,4},{newspaper,1},{apples,1},{pears,6},{milk,3}]
2> settle:total(BuyList).
105

同名不同目的函数

-module(calc).
-export([sum/1]).
sum(L) -> sum(L,0).
sum([],N) -> N;
sum([H|T],N) -> sum(T,H+N).

匿名函数 fun

1> Double = fun(X) -> 2*X end.
#Fun<erl_eval.6.99386804>
2> Double(4).
8
3> Hypot = fun(X,Y) -> math:sqrt(X*X + Y*Y) end.
#Fun<erl_eval.12.99386804>
4> Hypot(3,4).
5.0
5> TempConvert = fun({c,C}) -> {f,32 + C*9/5};
5>                              ({f,F}) -> {c, (F-32)*5/9}
5>                          end.
#Fun<erl_eval.6.99386804>
6> TempConvert({c,100}).
{f,212.0}
7> TempConvert({f,212}).
{c,100.0}

以 fun 为参数的函数

1> Double = fun(X) -> 2*X end.
#Fun<erl_eval.6.99386804>
2> L = [1,2,3,4].
[1,2,3,4]
3> lists:map(Double, L).
[2,4,6,8]
4> Even = fun(X) -> (X rem 2) =:= 0 end.
#Fun<erl_eval.6.99386804>
5> Even(8).
true
6> Even(7).
false
7> lists:map(Even, [1,2,3,4,5,6,7,8]).
[false,true,false,true,false,true,false,true]
8> lists:filter(Even, [1,2,3,4,5,6,7,8]).
[2,4,6,8]

**返回 fun 的函数

1> Fruit = [apple,pear,orange].
[apple,pear,orange]
2> MakeTest = fun(L) -> (fun(X) -> lists:member(X, L) end) end.
#Fun<erl_eval.6.99386804>
3> IsFruit = MakeTest(Fruit).
#Fun<erl_eval.6.99386804>
4> IsFruit(pear).
true
5> IsFruit(apple).
true
6> IsFruit(dog).
false
7> lists:filter(IsFruit, [dog,orange,cat,apple,bear]).
[orange,apple]

定制自己的抽象流程控制

%% for 循环
-module(lib_misc).
-export([for/3]).
for(Max,Max,F) -> [F(Max)];
for(I,Max,F) -> [F(I)|for(I+1, Max, F)].

1> c(lib_misc).
{ok,lib_misc}
2> lib_misc:for(1,10,fun(I) -> I*I end).
[1,4,9,16,25,36,49,64,81,100]

简单的列表处理

-module(mylist).
-export([sum/1]).
sum([H|T]) -> H + sum(T);
sum([]) -> 0.
map(_,[]) -> [];
map(F,[H|T]) -> [F(H)|map(F,T)].

1> c(mylist).
{ok,mylist}
2> L = [1,2,3].
[1,2,3]
3> mylist:sum(L).
4> mylist:map(fun(X)->2*X end,L). 
[2,4,6]

列表解析

%% [F(X) || X <- L]
1> L = [1,2,3,4,5].
[1,2,3,4,5]
2> [2*X || X <- L].
[2,4,6,8,10]
3> BuyList = [{oranges,4},{newspaper,1},{apples,1},{pears,6},{milk,3}].
[{oranges,4},{newspaper,1},{apples,1},{pears,6},{milk,3}]
4> [{Name,2*Number} || {Name,Number} <- BuyList].
[{oranges,8},{newspaper,2},{apples,2},{pears,12},{milk,6}]

快速排序

-module(lib_misc).
-export([qsort/1]).
qsort([]) -> [];
qsort([Pivot|T]) ->
        qsort([X || X<-T,X<Pivot])
        ++ [Pivot] ++
        qsort([X || X<-T,X>=Pivot]).

1> c(lib_misc).
{ok,lib_misc}
2> L = [12,32,56,11,0,234,52,9,134,526,21,7,83].
[12,32,56,11,0,234,52,9,134,526,21,7,83]
3> lib_misc:qsort(L).
[0,7,9,11,12,21,32,52,56,83,134,234,526]

毕达哥拉斯三元组

-module(lib_misc).
-export([pythag/1]).
pythag(N) ->
    [{A,B,C} || 
        A<-lists:seq(1,N),
        B<-lists:seq(1,N),
        C<-lists:seq(1,N),
        A+B+C =< N,
        A*A+B*B =:= C*C
    ].

1> c(lib_misc).
{ok,lib_misc}
2> lib_misc:pythag(16).
[{3,4,5},{4,3,5}]

断言

max(X,Y) when X>Y -> X;
max(X,Y) -> Y.

记录

%% records.hrl
-record(todo,{status=reminder,who=john,text}).
1> rr("records.hrl").
[todo]
2> X=#todo{}.
#todo{status = reminder,who = john,text = undefined}
3> X1 = #todo{status=urgent,text="Fix errata in book"}.
#todo{status = urgent,who = john,text = "Fix errata in book"}
4> X2 = X1#todo{status=done}.
#todo{status = done,who = john,text = "Fix errata in book"}
%% 从记录中提取字段
5> #todo{who=W,text=Txt} = X2.
#todo{status = done,who = john,text = "Fix errata in book"}
6> W.
john
7> Txt.
"Fix errata in book"
8> X2#todo.text.
"Fix errata in book"

case 语句

is_even(X) ->
        case (X rem 2) of
                0 -> true;
                1 -> false
        end.

if 语句

is_odd(X) ->
        if
                (X rem 2)==0 ->
                        false;
                (X rem 2)==1 ->
                        true
        end.

累加器

odds_and_evens_acc(L) ->
        odds_and_evens_acc(L,[],[]).
odds_and_evens_acc([H|T],Odds,Evens) ->
        case (H rem 2) of
                1 -> odds_and_evens_acc(T,[H|Odds],Evens);
                0 -> odds_and_evens_acc(T,Odds,[H|Evens])
        end;
odds_and_evens_acc([],Odds,Evens) ->
        {Odds,Evens}.

1> lib_misc:odds_and_evens_acc([1,2,3,4,5,6,7,8,9]).
{[9,7,5,3,1],[8,6,4,2]}

作者 Github : tojohnonly , 博客 : EnskDeCode