- -module(tut1). %这个表示本模块叫tut1, 该模块所在文件名字需要是tut1.erl,注意代码的结束符是一个点"."
-
-export([fac/1, mult/2]). %导出了2个函数,fac和mult。 fac有一个参数,mult有2个参数
-
-
fac(1) ->
-
1; %引号表示这个函数还有更多的部分
-
fac(N) -> %这个函数的第二部分
-
N * fac(N - 1). %这里的"."表示这个函数结束了
-
-
mult(X, Y) ->
-
X * Y.
-
-
编译:
-
c(tut1).
-
运行:
-
tut1:mult(3,4)
-
12
Atom的概念:
Erlang里有种数据类型叫做Atom,由一个小写字母开头。例如:charle, centimeter, inch. Atom只是名字,他们不像变量那样可以被赋值。
- -module(tut2).
-
-export([convert/2]).
-
-
convert(M, inch) ->
-
M / 2.54;
-
-
convert(N, centimeter) ->
-
N * 2.54.
-
-
1>c(tut2).
-
2>tut2:convert(3, inch)
-
3>tut2:convert(3, centimeter)
-
4>tut2:convert(3, miles)
-
** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)
可以通过v/1来看错误的history list.
- 5>v(4)
-
{'EXIT',{function_clause,[{tut2,convert,
-
[3,miles],
-
[{file,"tut2.erl"},{line,4}]},
-
{erl_eval,do_apply,5,[{file,"erl_eval.erl"},{line,482}]},
-
{shell,exprs,7,[{file,"shell.erl"},{line,666}]},
-
{shell,eval_exprs,7,[{file,"shell.erl"},{line,621}]},
-
{shell,eval_loop,3,[{file,"shell.erl"},{line,606}]}]}}
Tuples
Tuples可以把相关的值或变量组成一个group,用{}表示,如可把上面的表示为{3, inch}, {3, centimeter},比如改写上面的inch和centimeter互换的程序。
- -module(tut3).
-
-export([convert_length/1]).
-
-
convert_length({centimeter, X}) ->
-
{inch, X / 2.54};
-
convert_length({inch, Y}) ->
-
{centimeter, Y * 2.54}.
-
-
14> c(tut3).
-
{ok,tut3}
-
15> tut3:convert_length({inch, 5}). %传入的是一个Tuples
-
{centimeter,12.7}
-
16> tut3:convert_length(tut3:convert_length({inch, 5})).
-
{inch,5.0}
可以把Tuples的每一项称为一个元素,比如{moscow,{c,-10}}, 第一个元素是moscow, 第二个元素是{c,-10}.
List
List在Erlang里用[]表示,如
[{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},
{paris, {f, 28}}, {london, {f, 36}}]
可以用"|"来分别看List的每部分,如:
- 17> [First |TheRest] = [1,2,3,4,5].
-
[1,2,3,4,5]
-
18> First.
- 1
-
19> TheRest.
-
[2,3,4,5]
-
-
20> [E1, E2 | R] = [1,2,3,4,5,6,7].
-
[1,2,3,4,5,6,7]
-
21> E1.
- 1
-
22> E2.
- 2
-
23> R.
-
[3,4,5,6,7]
-
-
24> [A, B | C] = [1, 2].
-
[1,2]
-
25> A.
- 1
-
26> B.
- 2
-
27> C.
-
[]
变量:
在Erlang里,每个变量在它自己的上下文中只能被赋值一次,也就是说赋值之后,它的值就不能改变了,这和别的语言是不同的。如:
- 39> M = 5.
-
5
-
40> M = 6.
-
** exception error: no match of right hand side value 6
-
41> M = M + 1.
-
** exception error: no match of right hand side value 6
-
42> N = M + 1.
-
6
下面看一个计算List的长度的程序:
- -module(tut4).
-
-
-export([list_length/1]).
-
-
list_length([]) ->
-
0;
-
list_length([First | Rest]) ->
-
1 + list_length(Rest).
编译运行和输出:
28> c(tut4).
{ok,tut4}
29> tut4:list_length([1,2,3,4,5,6,7]).
7
看一个比大小的程序:
- %% Author: Lizhuohua
- %% Created: 2012-3-1
- %% Description: TODO: Add description to tut
- -module(tut6).
- -export([list_max/1, list_min/1]).
-
list_max([Head|Rest]) ->
- list_max(Rest, Head).
-
list_max([], Res) ->
- Res;
-
-
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
-
list_max(Rest, Head);
-
list_max([Head|Rest], Result_so_far) ->
-
list_max(Rest, Result_so_far).
-
-
list_min([Head|Rest]) ->
-
list_min(Rest, Head).
-
-
list_min([], Res) ->
-
Res;
-
list_min([Head|Rest], Result_so_far) when Head < Result_so_far ->
-
list_min(Rest, Head);
-
list_min([Head|Rest], Result_so_far) ->
-
list_min(Rest, Result_so_far).
- -module(tut8).
-
-export([reverse/1]).
-
-
reverse(List) ->
-
reverse(List, []).
-
-
reverse([Head | Rest], Reversed_List) ->
-
reverse(Rest, [Head | Reversed_List]);
-
reverse([], Reversed_List) ->
-
Reversed_List.
-
-
编译运行和输出:
-
52> c(tut8).
-
{ok,tut8}
-
53> tut8:reverse([1,2,3]).
-
[3,2,1]
到目前位置最复杂的程序来了:
- -module(tut7).
-
-export([format_temps/1]).
-
-
format_temps(List_of_cities) ->
-
Converted_List = convert_list_to_c(List_of_cities),
-
print_temp(Converted_List),
-
{Max_city, Min_city} = find_max_and_min(Converted_List),
-
print_max_and_min(Max_city, Min_city).
-
-
convert_list_to_c([{Name, {f, Temp}} | Rest]) ->
-
Converted_City = {Name, {c, (Temp -32)* 5 / 9}},
-
[Converted_City | convert_list_to_c(Rest)];
-
-
convert_list_to_c([City | Rest]) ->
-
[City | convert_list_to_c(Rest)];
-
-
convert_list_to_c([]) ->
-
[].
-
-
print_temp([{Name, {c, Temp}} | Rest]) ->
-
io:format("~-15w ~w c~n", [Name, Temp]), %解释一下这里的io:format.io是Erlang里的一个标准模块,包含了很多格式化输入输出的函数。通过%erl -man io可查询io模块的使用说明。
-
print_temp(Rest);
-
print_temp([]) ->
-
ok.
-
-
find_max_and_min([City | Rest]) ->
-
find_max_and_min(Rest, City, City).
-
-
find_max_and_min([{Name, {c, Temp}} | Rest],
-
{Max_Name, {c, Max_Temp}},
-
{Min_Name, {c, Min_Temp}}) ->
-
if
-
Temp > Max_Temp ->
-
Max_City = {Name, {c, Temp}}; % Change
-
true ->
-
Max_City = {Max_Name, {c, Max_Temp}} % Unchanged
-
end,
-
if
-
Temp < Min_Temp ->
-
Min_City = {Name, {c, Temp}}; % Change
-
true ->
-
Min_City = {Min_Name, {c, Min_Temp}} % Unchanged
-
end,
-
find_max_and_min(Rest, Max_City, Min_City);
-
-
find_max_and_min([], Max_City, Min_City) ->
-
{Max_City, Min_City}.
-
-
print_max_and_min({Max_name, {c, Max_temp}}, {Min_name, {c, Min_temp}}) ->
-
io:format("Max temperature was ~w c in ~w~n", [Max_temp, Max_name]),
-
io:format("Min temperature was ~w c in ~w~n", [Min_temp, Min_name]).
编译输出和运行:
58> c(tut7).
{ok, tut7}
59> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
moscow -10 c
cape_town 21.11111111111111 c
stockholm -4 c
paris -2.2222222222222223 c
london 2.2222222222222223 c
Max temperature was 21.11111111111111 c in cape_town
Min temperature was -10 c in moscow
ok
If的格式:
- %% Author: Lizhuohua
-
%% Created: 2012-3-2
-
%% Description: TODO: Add description to tut7
-
-module(tut7).
-
-export([test_if/2]).
-
-
test_if(A, B) ->
-
if
-
A == 5 ->
-
io:format("A == 5~n", []),
-
a_equals_5,
-
A < B;
-
B == 6 ->
-
io:format("B == 6~n", []),
-
b_equals_6;
-
A == 2, B == 3 -> %i.e. A equals 2 and B equals 3
-
io:format("A == 2, B == 3~n", []),
-
a_equals_2_b_equals_3;
-
A == 5 ; B == 7 -> %i.e. A equals 1 or B equals 7
-
io:format("A == 1 ; B == 7~n", []),
-
a_equals_1_or_b_equals_7
-
end.
case的格式:
之前我们的程序是:
- convert_length({centimeter, X}) ->
-
{inch, X / 2.54};
-
convert_length({inch, Y}) ->
-
{centimeter, Y * 2.54}.
利用case:
- -module(tut10).
-
-export([convert_length/1]).
-
-
convert_length(Length) ->
-
case Length of
-
{centimeter, X} ->
-
{inch, X / 2.54};
-
{inch, Y} ->
-
{centimeter, Y * 2.54}
-
end.
结合if和case的程序:
- -module(tut11).
-
-export([month_length/2]).
-
-
month_length(Year, Month) ->
-
%% All years divisible by 400 are leap
-
%% Years divisible by 100 are not leap (except the 400 rule above)
-
%% Years divisible by 4 are leap (except the 100 rule above)
-
Leap = if
-
trunc(Year / 400) * 400 == Year ->
-
leap;
-
trunc(Year / 100) * 100 == Year ->
-
not_leap;
-
trunc(Year / 4) * 4 == Year ->
-
leap;
-
true ->
-
not_leap
-
end,
-
case Month of
-
sep -> 30;
-
apr -> 30;
-
jun -> 30;
-
nov -> 30;
-
feb when Leap == leap -> 29;
-
feb -> 28;
-
jan -> 31;
-
mar -> 31;
-
may -> 31;
-
jul -> 31;
-
aug -> 31;
-
oct -> 31;
-
dec -> 31
-
end.
High Order Functions
- 先看list的foreach方法
-
foreach(Fun, [First|Rest]) ->
-
Fun(First),
-
foreach(Fun, Rest);
-
foreach(Fun, []) ->
-
ok.
-
foreach对List里面的每一个元素运行Fun函数,类似的还有map函数
-
map(Fun, [First|Rest]) ->
-
[Fun(First)|map(Fun,Rest)];
-
map(Fun, []) ->
-
[].
-
-
如
-
88> Add_3 = fun(X) -> X + 3 end.
-
#Fun<erl_eval.5.123085357>
-
89> lists:map(Add_3, [1,2,3]).
-
[4,5,6]
-
-
另一个例子:
-
90> Print_City = fun({City, {X, Temp}}) -> io:format("~-15w ~w ~w~n",
-
[City, X, Temp]) end.
-
#Fun<erl_eval.5.123085357>
-
91> lists:foreach(Print_City, [{moscow, {c, -10}}, {cape_town, {f, 70}},
-
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
-
moscow c -10
-
cape_town f 70
-
stockholm c -4
-
paris f 28
-
london f 36
-
ok
-
-
也可以写作:
-
-module(tut13).
-
-export([convert_list_to_c/1]).
-
-
convert_to_c({Name, {f, Temp}}) ->
-
{Name, {c, trunc((Temp - 32) * 5 / 9)}};
-
convert_to_c({Name, {c, Temp}}) ->
-
{Name, {c, Temp}}.
-
-
convert_list_to_c(List) ->
-
lists:map(fun convert_to_c/1, List). %这里就是对List中的每个元素调用convert_to_c/1.
-
-
List还包括sort(Fun, List)函数, 其中Fun是包含2个参数。Fun这个函数应该返回true,如果第一个参数小于第二个参数。例如:
-
-module(tut13).
-
-
-export([convert_list_to_c/1]).
-
-
convert_to_c({Name, {f, Temp}}) ->
-
{Name, {c, trunc((Temp - 32) * 5 / 9)}};
-
convert_to_c({Name, {c, Temp}}) ->
-
{Name, {c, Temp}}.
-
-
convert_list_to_c(List) ->
-
New_list = lists:map(fun convert_to_c/1, List),
-
lists:sort(fun({_, {c, Temp1}}, {_, {c, Temp2}}) ->
-
Temp1 < Temp2 end, New_list).
-
-
93> c(tut13).
-
{ok,tut13}
-
94> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},
-
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
-
[{moscow,{c,-10}},
-
{stockholm,{c,-4}},
-
{paris,{c,-2}},
-
{london,{c,2}},
-
{cape_town,{c,21}}]
-
-
注意这里有个匿名变量"_", 它代表了一个变量,但是因为我们不关心它的值。
阅读(1422) | 评论(0) | 转发(0) |