在erlang中,List操作在前面的例子中,已經多次使用.
接著來看看List comprehension,目前尚未看到有合適的中文翻譯,
故在此均保留使用英文.
直接看例子就能理解了.
1> L = [1,2,3,4,5].
[1,2,3,4,5]
2> lists:map(fun(X) -> 2 * X end, L).
[2,4,6,8,10]
3> [2 * X || X <- L].
[2,4,6,8,10]
第2是使用lists:map()函式來處理,第3就是使用List comprehension,
相對簡明.
接著來看一下應用,我們來算畢達哥拉斯組數.
-module(p1009).
-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
].
編譯及執行:
4> c("p1009").
{ok,p1009}
5> p1009:pythag(30).
[{3,4,5},{4,3,5},{5,12,13},{6,8,10},{8,6,10},{12,5,13}]
上面的程式運用了lists:seq()來產生序列數字;
=:= 用來判斷是否相等,與一般程式語言的 ==, 符號略有差異.
其實就把畢達哥拉斯組數的數學公式放進去,也不必像一般程式
語言那樣要寫三重迴圈,再加邏輯判斷.
接著來介紹守衛(Guard),守衛可以用來增強模式比對.
例如要寫一個max(X,Y)的函數.就可以利用守衛.
我們把上面程式增加max()的定義,增加-export部份的內容.
-module(p1009).
-export([pythag/1,max/2]).
%%% ^^^^^^
%%% Add this
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
].
%%% Apped here
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.
max()函數很簡單,就不附操作情況.
注意到上面的 % ,這是erlang註解用的符號;
慣例上,程式前面的註解,用來說明程式的功能
等meta data,會用%% 開頭.
守衛還有以下的守衛函數可以搭配使用.
is_atom(X)
is_binary(X)
is_constant(X)
is_float(X)
is_function(X)
is_function(X, N)
is_integer(X)
is_list(X)
is_map(X)
is_number(X)
is_pid(X)
is_pmod(X)
is_port(X)
is_reference(X)
is_tuple(X)
is_record(X,Tag)
is_record(X,Tag,N)