Chinaunix首页 | 论坛 | 博客
  • 博客访问: 751787
  • 博文数量: 130
  • 博客积分: 2951
  • 博客等级: 少校
  • 技术积分: 1875
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-04 18:32
文章分类

全部博文(130)

文章存档

2013年(1)

2012年(129)

分类: Python/Ruby

2012-03-02 11:13:53

  1. -module(tut1). %这个表示本模块叫tut1, 该模块所在文件名字需要是tut1.erl,注意代码的结束符是一个点"."
  2. -export([fac/1, mult/2]). %导出了2个函数,fac和mult。 fac有一个参数,mult有2个参数

  3. fac(1) ->
  4.     1; %引号表示这个函数还有更多的部分
  5. fac(N) -> %这个函数的第二部分
  6.     N * fac(N - 1). %这里的"."表示这个函数结束了

  7. mult(X, Y) ->
  8.     X * Y.

  9. 编译:
  10. c(tut1).
  11. 运行:
  12. tut1:mult(3,4)
  13. 12

Atom的概念:
Erlang里有种数据类型叫做Atom,由一个小写字母开头。例如:charle, centimeter, inch. Atom只是名字,他们不像变量那样可以被赋值。
  1. -module(tut2).
  2. -export([convert/2]).

  3. convert(M, inch) ->
  4.     M / 2.54;

  5. convert(N, centimeter) ->
  6.     N * 2.54.

  7. 1>c(tut2).
  8. 2>tut2:convert(3, inch)
  9. 3>tut2:convert(3, centimeter)
  10. 4>tut2:convert(3, miles)
  11. ** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)
可以通过v/1来看错误的history list.
  1. 5>v(4)
  2. {'EXIT',{function_clause,[{tut2,convert,
  3.                                 [3,miles],
  4.                                 [{file,"tut2.erl"},{line,4}]},
  5.                           {erl_eval,do_apply,5,[{file,"erl_eval.erl"},{line,482}]},
  6.                           {shell,exprs,7,[{file,"shell.erl"},{line,666}]},
  7.                           {shell,eval_exprs,7,[{file,"shell.erl"},{line,621}]},
  8.                           {shell,eval_loop,3,[{file,"shell.erl"},{line,606}]}]}}

Tuples
Tuples可以把相关的值或变量组成一个group,用{}表示,如可把上面的表示为{3, inch}, {3, centimeter},比如改写上面的inch和centimeter互换的程序。
  1. -module(tut3).
  2. -export([convert_length/1]).

  3. convert_length({centimeter, X}) ->
  4.     {inch, X / 2.54};
  5. convert_length({inch, Y}) ->
  6.     {centimeter, Y * 2.54}.

  7. 14> c(tut3).
  8.     {ok,tut3}
  9. 15> tut3:convert_length({inch, 5}). %传入的是一个Tuples
  10.     {centimeter,12.7}
  11. 16> tut3:convert_length(tut3:convert_length({inch, 5})).
  12.     {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的每部分,如:
  1. 17> [First |TheRest] = [1,2,3,4,5].
  2.     [1,2,3,4,5]
  3. 18> First.
  4.     1
  5. 19> TheRest.
  6.     [2,3,4,5]

  7. 20> [E1, E2 | R] = [1,2,3,4,5,6,7].
  8.     [1,2,3,4,5,6,7]
  9. 21> E1.
  10.     1
  11. 22> E2.
  12.     2
  13. 23> R.
  14.     [3,4,5,6,7]

  15. 24> [A, B | C] = [1, 2].
  16.     [1,2]
  17. 25> A.
  18.     1
  19. 26> B.
  20.     2
  21. 27> C.
  22.     []

变量:
在Erlang里,每个变量在它自己的上下文中只能被赋值一次,也就是说赋值之后,它的值就不能改变了,这和别的语言是不同的。如:
  1. 39> M = 5.
  2. 5
  3. 40> M = 6.
  4. ** exception error: no match of right hand side value 6
  5. 41> M = M + 1.
  6. ** exception error: no match of right hand side value 6
  7. 42> N = M + 1.
  8. 6

下面看一个计算List的长度的程序:
  1. -module(tut4).

  2. -export([list_length/1]).

  3. list_length([]) ->
  4.     0;
  5. list_length([First | Rest]) ->
  6.     1 + list_length(Rest).
编译运行和输出:
28> c(tut4).
{ok,tut4}
29> tut4:list_length([1,2,3,4,5,6,7]).
7

看一个比大小的程序:
  1. %% Author: Lizhuohua
  2. %% Created: 2012-3-1
  3. %% Description: TODO: Add description to tut
  4. -module(tut6).
  5. -export([list_max/1, list_min/1]).

  6. list_max([Head|Rest]) ->
  7.     list_max(Rest, Head).

  8. list_max([], Res) ->
  9.     Res;

  10. list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
  11.     list_max(Rest, Head);
  12. list_max([Head|Rest], Result_so_far) ->
  13.     list_max(Rest, Result_so_far).

  14. list_min([Head|Rest]) ->
  15.     list_min(Rest, Head).

  16. list_min([], Res) ->
  17.     Res;
  18. list_min([Head|Rest], Result_so_far) when Head < Result_so_far ->
  19.     list_min(Rest, Head);
  20. list_min([Head|Rest], Result_so_far) ->
  21.     list_min(Rest, Result_so_far).

看一个逆转List的程序
  1. -module(tut8).
  2. -export([reverse/1]).

  3. reverse(List) ->
  4.     reverse(List, []).

  5. reverse([Head | Rest], Reversed_List) ->
  6.     reverse(Rest, [Head | Reversed_List]);
  7. reverse([], Reversed_List) ->
  8.     Reversed_List.

  9. 编译运行和输出:
  10. 52> c(tut8).
  11. {ok,tut8}
  12. 53> tut8:reverse([1,2,3]).
  13. [3,2,1]
到目前位置最复杂的程序来了:
  1. -module(tut7).
  2. -export([format_temps/1]).

  3. format_temps(List_of_cities) ->
  4.     Converted_List = convert_list_to_c(List_of_cities),
  5.     print_temp(Converted_List),
  6.     {Max_city, Min_city} = find_max_and_min(Converted_List),
  7.     print_max_and_min(Max_city, Min_city).

  8. convert_list_to_c([{Name, {f, Temp}} | Rest]) ->
  9.     Converted_City = {Name, {c, (Temp -32)* 5 / 9}},
  10.     [Converted_City | convert_list_to_c(Rest)];

  11. convert_list_to_c([City | Rest]) ->
  12.     [City | convert_list_to_c(Rest)];

  13. convert_list_to_c([]) ->
  14.     [].

  15. print_temp([{Name, {c, Temp}} | Rest]) ->
  16.     io:format("~-15w ~w c~n", [Name, Temp]), %解释一下这里的io:format.io是Erlang里的一个标准模块,包含了很多格式化输入输出的函数。通过%erl -man io可查询io模块的使用说明。
  17.     print_temp(Rest);
  18. print_temp([]) ->
  19.     ok.

  20. find_max_and_min([City | Rest]) ->
  21.     find_max_and_min(Rest, City, City).

  22. find_max_and_min([{Name, {c, Temp}} | Rest],
  23.          {Max_Name, {c, Max_Temp}},
  24.          {Min_Name, {c, Min_Temp}}) ->
  25.     if
  26.         Temp > Max_Temp ->
  27.             Max_City = {Name, {c, Temp}}; % Change
  28.         true ->
  29.             Max_City = {Max_Name, {c, Max_Temp}} % Unchanged
  30.     end,
  31.     if
  32.          Temp < Min_Temp ->
  33.             Min_City = {Name, {c, Temp}}; % Change
  34.         true ->
  35.             Min_City = {Min_Name, {c, Min_Temp}} % Unchanged
  36.     end,
  37.     find_max_and_min(Rest, Max_City, Min_City);

  38. find_max_and_min([], Max_City, Min_City) ->
  39.     {Max_City, Min_City}.

  40. print_max_and_min({Max_name, {c, Max_temp}}, {Min_name, {c, Min_temp}}) ->
  41.     io:format("Max temperature was ~w c in ~w~n", [Max_temp, Max_name]),
  42.     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的格式:
  1. %% Author: Lizhuohua
  2. %% Created: 2012-3-2
  3. %% Description: TODO: Add description to tut7
  4. -module(tut7).
  5. -export([test_if/2]).

  6. test_if(A, B) ->
  7.     if
  8.         A == 5 ->
  9.             io:format("A == 5~n", []),
  10.             a_equals_5,
  11.             A < B;
  12.         B == 6 ->
  13.             io:format("B == 6~n", []),
  14.             b_equals_6;
  15.         A == 2, B == 3 -> %i.e. A equals 2 and B equals 3
  16.             io:format("A == 2, B == 3~n", []),
  17.             a_equals_2_b_equals_3;
  18.         A == 5 ; B == 7 -> %i.e. A equals 1 or B equals 7
  19.             io:format("A == 1 ; B == 7~n", []),
  20.             a_equals_1_or_b_equals_7
  21.     end.
case的格式:
之前我们的程序是:
  1. convert_length({centimeter, X}) ->
  2.     {inch, X / 2.54};
  3. convert_length({inch, Y}) ->
  4.     {centimeter, Y * 2.54}.
利用case:
  1. -module(tut10).
  2. -export([convert_length/1]).

  3. convert_length(Length) ->
  4.     case Length of
  5.         {centimeter, X} ->
  6.             {inch, X / 2.54};
  7.         {inch, Y} ->
  8.             {centimeter, Y * 2.54}
  9.     end.
结合if和case的程序:
  1. -module(tut11).
  2. -export([month_length/2]).

  3. month_length(Year, Month) ->
  4.     %% All years divisible by 400 are leap
  5.     %% Years divisible by 100 are not leap (except the 400 rule above)
  6.     %% Years divisible by 4 are leap (except the 100 rule above)
  7.     Leap = if
  8.         trunc(Year / 400) * 400 == Year ->
  9.             leap;
  10.         trunc(Year / 100) * 100 == Year ->
  11.             not_leap;
  12.         trunc(Year / 4) * 4 == Year ->
  13.             leap;
  14.         true ->
  15.             not_leap
  16.     end,
  17.     case Month of
  18.         sep -> 30;
  19.         apr -> 30;
  20.         jun -> 30;
  21.         nov -> 30;
  22.         feb when Leap == leap -> 29;
  23.         feb -> 28;
  24.         jan -> 31;
  25.         mar -> 31;
  26.         may -> 31;
  27.         jul -> 31;
  28.         aug -> 31;
  29.         oct -> 31;
  30.         dec -> 31
  31.     end.
High Order Functions
  1. 先看list的foreach方法
  2. foreach(Fun, [First|Rest]) ->
  3.     Fun(First),
  4.     foreach(Fun, Rest);
  5. foreach(Fun, []) ->
  6.     ok.
  7. foreach对List里面的每一个元素运行Fun函数,类似的还有map函数
  8. map(Fun, [First|Rest]) ->
  9.     [Fun(First)|map(Fun,Rest)];
  10. map(Fun, []) ->
  11.     [].


  12. 88> Add_3 = fun(X) -> X + 3 end.
  13. #Fun<erl_eval.5.123085357>
  14. 89> lists:map(Add_3, [1,2,3]).
  15. [4,5,6]

  16. 另一个例子:
  17. 90> Print_City = fun({City, {X, Temp}}) -> io:format("~-15w ~w ~w~n",
  18.                         [City, X, Temp]) end.
  19. #Fun<erl_eval.5.123085357>
  20. 91> lists:foreach(Print_City, [{moscow, {c, -10}}, {cape_town, {f, 70}},
  21. {stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
  22. moscow c -10
  23. cape_town f 70
  24. stockholm c -4
  25. paris f 28
  26. london f 36
  27. ok

  28. 也可以写作:
  29. -module(tut13).
  30. -export([convert_list_to_c/1]).

  31. convert_to_c({Name, {f, Temp}}) ->
  32.     {Name, {c, trunc((Temp - 32) * 5 / 9)}};
  33. convert_to_c({Name, {c, Temp}}) ->
  34.     {Name, {c, Temp}}.

  35. convert_list_to_c(List) ->
  36.     lists:map(fun convert_to_c/1, List). %这里就是对List中的每个元素调用convert_to_c/1.

  37. List还包括sort(Fun, List)函数, 其中Fun是包含2个参数。Fun这个函数应该返回true,如果第一个参数小于第二个参数。例如:
  38. -module(tut13).

  39. -export([convert_list_to_c/1]).

  40. convert_to_c({Name, {f, Temp}}) ->
  41.     {Name, {c, trunc((Temp - 32) * 5 / 9)}};
  42. convert_to_c({Name, {c, Temp}}) ->
  43.     {Name, {c, Temp}}.

  44. convert_list_to_c(List) ->
  45.     New_list = lists:map(fun convert_to_c/1, List),
  46.     lists:sort(fun({_, {c, Temp1}}, {_, {c, Temp2}}) ->
  47.                        Temp1 < Temp2 end, New_list).

  48. 93> c(tut13).
  49. {ok,tut13}
  50. 94> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},
  51. {stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
  52. [{moscow,{c,-10}},
  53.  {stockholm,{c,-4}},
  54.  {paris,{c,-2}},
  55.  {london,{c,2}},
  56.  {cape_town,{c,21}}]

  57. 注意这里有个匿名变量"_", 它代表了一个变量,但是因为我们不关心它的值。















阅读(1422) | 评论(0) | 转发(0) |
0

上一篇:步入Erlang

下一篇:AIX里查看历史命令

给主人留下些什么吧!~~