erlang 顺序编程-模块函数02

本文介绍了Erlang中的模块和函数概念。模块是代码的容器,以.erl为扩展名,编译后生成.beam文件。讨论了模块内的函数,包括模式匹配循环、函数数据类型(fun)及其在计算三角形斜边和转换温度中的应用。此外,还涉及了列表操作,如map、排序算法、毕达哥拉斯三元组、列表推导和回文构词,以及Erlang中的条件判断和流程控制结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模块是存放代码的地方

模块保存在扩展名为.erl的文件里,编译后生成.beam 

geometry.erl

-module(geometry).
-export([test/0,area/1]).

//添加测试代码
test() -> 
    12 = area({rectangle,3,4}),
    144 = area(square,12),
    tests_worked.

area({rectangle,Width,Height}) -> Width * Height;
area({square,Side})            -> Side * Side.



//调用,下面这个是shell 里的命令
c(geometry).
geometry:area({rectangle,10,5}).
geometry:area({square,3}).

模式匹配循环使用

shop.erl

-module(shop).
-export([cost/1]).

cost(oranges)   -> 5;
cost(newspaper) -> 8;
cost(apples)    -> 2;
cost(milk)      -> 7.

shop1.erl   调用total 计算Buy = [{oranges,4},{newspaper,2},{milk,7}] 的价格,这里的数字代表数量 

-module(shop1).
-export([total/1]).

total([{What,N}|T]) -> shop:cost(What) * N + total(T);
total([])           -> 0.

fun

代表函数的数据类型被称为fun。(lambda)

Double = fun(x) -> 2 * x end.

Double(2). //结果=4

求三角形斜边

Hypot = fun(X,Y) -> math:sqrt(X*X + Y*Y) end.
Hypot(3,4).  //结果是5.0

fun里的模式匹配,个转换华氏与摄氏温度

TempConvert = fun({c,C}) -> {f,32 + C * 9/5};
                 ({f,F}) -> {c,(F-32)*5/9}
              end.

lists:map  传递一个list过来然后消耗里面的值(消耗L里的值)

L = [1,2,3,4].
lists:map(fun(x) -> 2*X end,L).

=:= 判断是否相等

Even = fun(X) -> (X rem 2) =:= 0.

//结果 [false,true,false,true,false,true....]
lists:map(Even,[1,2,3,4,5,6,7]).

//结果 [2,4,6,8]
lists:filter(Even,[1,2,3,4,5,6,7,8]).

查询是否包含子元素,进2层,出2层

Fruit = [apple,pear,orange].

MakeTest = fun(L) -> (fun(X) -> lists:member(X,L) end) end.

IsFruit = MakeTest(Fruit).
//true
IsFruit(pear).
//false
IsFruit(dog).

//[orange,apple]
lists:filter(IsFruit,[dog,orange,cat,apple,bear]).

生成按照一定规律的递增数

for(Max,Max,F) -> [F(Max)];
for(I,Max,F)   -> [F(I)|for(I+1,Max,F)].


//shell调用
//[1,2,3,4,5,6,7,8,9]
lib:for(1,10,fun(I) -> I end).
//[1,3,9,16,25]
lib:for(1,5,fun(I) -> I*I end).

导入其他元组里的方法(元组内求和)  。(import 导入的方法可以直接使用,否则需要使用完全限定shop:cost

-module(shop2).
-export([total/1]).
-import(lists,[map/2,sum/1]).

total(L) -> 
    sum(map(fun({What,N}) -> shop:cost(What) end,L)).

列表推导

L = [1,2,3,4,5].
//新列表由原列表元素 * 2组成
[2*X || X <- L].

//计算总价
Buy = [{oranges,4},{apples,6},{milk,3}].
//名称转成价格
[{shop:cost(X),Number} || {X,Number} <- Buy].
//价格与数量相乘
[shop:cost(X) * Number || {X,Number} <- Buy].
//求和
lists:sum([shop:cost(X) * Number || {X,Number} <- Buy]).

//简化
map(F,L) -> [F(X) || X <- L].

//有过滤的作用,结果是[1,4]
[ X || {a,X} <- [{a,1},{b,2},{c,3},{a,4},"Hello","world"]].

排序算法(感觉类似快速排序),每次找到一个元素,小于它的元组放左边,大于的放右边。然后在分好的元组内继续找。

++ [Pivot] ++   //把元素与左右元组连接

qsort([]) -> [];
qsort([Pivot|T]) ->
    qsort([X || X <- T,X < Pivot])
    ++ [Pivot] ++
    qsort([X || X <- T, X >= pivot]).

毕达哥拉斯三元数组(名字像哥斯拉),勾股定理的三条边

lists:seq(1,N) 随机生成1~n的数,满足毕达哥拉斯三元组定理(感觉就是穷举,影响效率吧?)

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
    ].

回文构词(排列组合)(这个挺牛逼的,比java方便多了)

L -- [H] 从L种移除H元素。元组内遍历取第一个位置,剩下的依次取第二第三。。。。

perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L,T <- perms[l--[H]]].

关卡(一种结构,增加模式匹配的威力)

获取最大值,when类似if的作用,逗号是并且,分号是或者

max(X,Y) when X > Y -> X;
max(X,Y) -> Y.
//,逗号是并且的意思
//T是一个包含六个元素的元组,T中第三个元素的绝对值大于5,元组X的第4个元素与列表L的列表头相同
is_tuple(T), tuple_size(T) =:= 6,abs(element(3,T)) > 5
element(4,X) =:= hd(L)


//;分号是或者,is_integer是整数判断
X =:= dog; X =:= cat
is_integer(X),X > Y; abs(Y) < 23

也可以直接使用 or、orelse、and、andalse。(or、and 类似java里的| 、&    而orelse,andalse类似 || 、&&会断路 )

true (放在最后)关卡相当于else ,当其他失败时进入这个匹配

//失败
f(X) when (X == 0) or (1/X >2) -> ...
//成功
f(X) when (X == 0) orelse (1/X >2) -> ...


if
    Guard -> Expressions;
    Guard -> Expressions;
    true  -> Expressions

end

case 和 if

filter(P,[H|T]) ->
    case P(H) of
        true  -> [H|filter(P,T)];
        false -> filter(P,T)
    end;
filter(P,[]) -> [].


//不使用case
filter(P,[H|T]) -> filterl(P(H),H,P,T);
filter(P,[])    -> [].

filterl(true,H,P,T) -> [H|filter(P,T)];
filterl(false,H,P,T) -> [filter(P,T)].

erlang 如果没有true 关卡,最后少判断会报错

if    
    A > 0 -> do_this();
    true  -> do_ther()
end

自然顺序的列表:

  • 输入列表的头部提取元素,然后把它们添加到输出列表的头部,形成的结果是与输入列表顺序相反的输出列表
  •  如果顺序很重要,就调用lists:reverse/1这个高度优化过的函数。

list ++ [H] 在数据量很少的时候使用,否则会影响效率。

一次遍历,元素分组

odds_and_evens2(L) ->
    odds_and_evens_acc(L,[],[]).

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值