Erlang入門備忘錄(1):單行編程
來源:互聯網
上載者:User
把“Sequential Programming”翻譯成“單行編程”,與“Concurrent Programming”並行編程形成對應比較,比翻譯成“順序編程”要好。對應“並發編程”的是“單發編程”。當然,這樣咬文嚼字有些矯情。2.1 The Erlang ShellTo shutdown the Erlang system and the Erlang shell type Control-C.Another way to shutdown the Erlang system is by entering halt().2.2 Modules and Functions-module(tut1).-export([fac/1]).fac(1) -> 1;fac(N) -> N * fac(N - 1).Compile the file 5> c(tut1).{ok,tut1}And now calculate the factorial of 4. 6> tut1:fac(4).242.3 Atoms-module(tut2).-export([convert/2]).convert(M, inch) -> M / 2.54;convert(N, centimeter) -> N * 2.54.Compile and test: 9> c(tut2).{ok,tut2}10> tut2:convert(3, inch).1.181102362204724311> tut2:convert(7, centimeter).17.782.4 Tuples-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}).{centimeter,12.7}16> tut3:convert_length(tut3:convert_length({inch, 5})).{inch,5.0}2.5 Lists17> [First |TheRest] = [1,2,3,4,5].[1,2,3,4,5]18> First.119> 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.122> E2.223> R.[3,4,5,6,7]24> [A, B | C] = [1, 2].[1,2]25> A.126> B.227> C.[]-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]).7list_length([]) -> 0;list_length([First | Rest]) -> 1 + list_length(Rest).30> [97,98,99]."abc"2.6 Standard Modules and Manual Pages% erl -man ioERLANG MODULE DEFINITION io(3)MODULE io - Standard I/O Server Interface FunctionsDESCRIPTION This module provides an interface to standard Erlang IO servers. The output functions all return ok if they are suc- ...http://www.erlang.org/doc/r9b/doc/index.html2.7 Writing Output to a Terminal31> io:format("hello world~n", []).hello worldok32> io:format("this outputs one Erlang term: ~w~n", [hello]).this outputs one Erlang term: hellook33> io:format("this outputs two Erlang terms: ~w~w~n", [hello, world]).this outputs two Erlang terms: helloworldok34> io:format("this outputs two Erlang terms: ~w ~w~n", [hello, world]).this outputs two Erlang terms: hello worldok2.8 A Larger Example%% This module is in file tut5.erl-module(tut5).-export([format_temps/1]).%% Only this function is exportedformat_temps([])-> % No output for an empty list ok;format_temps([City | Rest]) -> print_temp(convert_to_celsius(City)), format_temps(Rest).convert_to_celsius({Name, {c, Temp}}) -> % No conversion needed {Name, {c, Temp}};convert_to_celsius({Name, {f, Temp}}) -> % Do the conversion {Name, {c, (Temp - 32) * 5 / 9}}.print_temp({Name, {c, Temp}}) -> io:format("~-15w ~w c~n", [Name, Temp]).35> c(tut5).{ok,tut5}36> tut5:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).moscow -10 ccape_town 21.11111111111111 cstockholm -4 cparis -2.2222222222222223 clondon 2.2222222222222223 cok2.9 Matching, Guards and Scope of Variables-module(tut6).-export([list_max/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).37> c(tut6).{ok,tut6}38> tut6:list_max([1,2,3,4,5,7,4,3,2,1]).739> M = 5.540> M = 6.** exception error: no match of right hand side value 641> M = M + 1.** exception error: no match of right hand side value 642> N = M + 1.643> {X, Y} = {paris, {f, 28}}.{paris,{f,28}}44> X.paris45> Y.{f,28}46> {X, Y} = {london, {f, 36}}.** exception error: no match of right hand side value {london,{f,36}}list_max([Head|Rest], Result_so_far) when Head > Result_so_far -> New_result_far = Head, list_max(Rest, New_result_far);2.10 More About Lists47> [M1|T1] = [paris, london, rome].[paris,london,rome]48> M1.paris49> T1.[london,rome]50> L1 = [madrid | T1].[madrid,london,rome]51> L1.[madrid,london,rome]-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]reverse([1|2,3], []) => reverse([2,3], [1|[]])reverse([2|3], [1]) => reverse([3], [2|[1])reverse([3|[]], [2,1]) => reverse([], [3|[2,1]])reverse([], [3,2,1]) => [3,2,1]-module(tut7).-export([format_temps/1]).format_temps(List_of_cities) -> convert_list_to_c(List_of_cities).convert_list_to_c([{Name, {f, F}} | Rest]) -> Converted_City = {Name, {c, (F -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([]) -> [].54> c(tut7).{ok, tut7}.55> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).[{moscow,{c,-10}}, {cape_town,{c,21.11111111111111}}, {stockholm,{c,-4}}, {paris,{c,-2.2222222222222223}}, {london,{c,2.2222222222222223}}]format_temps(List_of_cities) -> convert_list_to_c(List_of_cities).convert_list_to_c([]) -> [].-module(tut7).-export([format_temps/1]).format_temps(List_of_cities) -> Converted_List = convert_list_to_c(List_of_cities), print_temp(Converted_List).convert_list_to_c([{Name, {f, F}} | Rest]) -> Converted_City = {Name, {c, (F -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]), print_temp(Rest);print_temp([]) -> ok.56> c(tut7).{ok,tut7}57> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).moscow -10 ccape_town 21.11111111111111 cstockholm -4 cparis -2.2222222222222223 clondon 2.2222222222222223 cok-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]), 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 ccape_town 21.11111111111111 cstockholm -4 cparis -2.2222222222222223 clondon 2.2222222222222223 cMax temperature was 21.11111111111111 c in cape_townMin temperature was -10 c in moscowok2.11 If and Caseif Condition 1 -> Action 1; Condition 2 -> Action 2; Condition 3 -> Action 3; Condition 4 -> Action 4end-module(tut9).-export([test_if/2]).test_if(A, B) -> if A == 5 -> io:format("A == 5~n", []), a_equals_5; 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 == 1 ; 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.60> c(tut9).{ok,tut9}61> tut9:test_if(5,33).A == 5a_equals_562> tut9:test_if(33,6).B == 6b_equals_663> tut9:test_if(2, 3).A == 2, B == 3a_equals_2_b_equals_364> tut9:test_if(1, 33).A == 1 ; B == 7a_equals_1_or_b_equals_765> tut9:test_if(33, 7).A == 1 ; B == 7a_equals_1_or_b_equals_766> tut9:test_if(33, 33).** exception error: no true branch found when evaluating an if expression in function tut9:test_if/2convert_length({centimeter, X}) -> {inch, X / 2.54};convert_length({inch, Y}) -> {centimeter, Y * 2.54}.-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.67> c(tut10).{ok,tut10}68> tut10:convert_length({inch, 6}).{centimeter,15.24}69> tut10:convert_length({centimeter, 2.5}).{inch,0.984251968503937}-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.70> c(tut11).{ok,tut11}71> tut11:month_length(2004, feb).2972> tut11:month_length(2003, feb).2873> tut11:month_length(1947, aug).312.12 Built In Functions (BIFs)74> 2004 rem 400.4Year rem 400 == 0 -> leap;75> trunc(5.6).576> round(5.6).677> length([a,b,c,d]).478> float(5).5.079> is_atom(hello).true80> is_atom("hello").false81> is_tuple({paris, {c, 30}}).true82> is_tuple([paris, {c, 30}]).false83> atom_to_list(hello)."hello"84> list_to_atom("goodbye").goodbye85> integer_to_list(22)."22"2.13 Higher Order Functions (Funs)86> Xf = fun(X) -> X * 2 end.#Fun<erl_eval.5.123085357>87> Xf(5).10foreach(Fun, [First|Rest]) -> Fun(First), foreach(Fun, Rest);foreach(Fun, []) -> ok.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 -10cape_town f 70stockholm c -4paris f 28london f 36ok-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).92> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).[{moscow,{c,-10}}, {cape_town,{c,21}}, {stockholm,{c,-4}}, {paris,{c,-2}}, {london,{c,2}}]lists:map(fun convert_to_c/1, List)-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}}]