Erlang の lists モジュールを一通り試す - その1
最近、Erlang のコードを読んでいて、lists:any
という関数が出てきたのだが、知らなかったので調べた。ついでに、他の関数も一通り眺めておく。
公式URL: http://erlang.org/doc/man/lists.html
all/2 関数
all(Pred, List) -> boolean()
Types
Pred = fun((Elem :: T) -> boolean()) List = [T] T = term()
Pred(Elem) がすべてのElem について true を返す場合はtrueを、それ以外の場合はfalseを返す。Pred は変数で関数がバインドされている。こんとき、第1引数 (Pred) に渡す関数は、boolean()
を返す必要がある。
$ erl ...(省略) > IsAtom = fun(X) -> is_atom(X) end. #Fun<erl_eval.6.99386804> > lists:all(IsAtom, [a,b,c,d,e]). true > lists:all(IsAtom, [a,b,c,d,e,1]). false
上記の例は、IsAtomという変数に、fun(X) -> is_atom(X) end.
という無名関数をバインドしている。IsAtomを第1引数に、[a, b, c, d, e]
というリストを第2引数に渡すと、リストの1つづつをIsAtomの関数で処理する。IsAtomの関数の実態はis_atom(X)
関数で渡されたリストの1つがX
に入って、X
がアトムかどうかをチェックする。X
がアトムなら true を返す。1つ目の例は、[a, b, c, d, e]
はすべて atom なので、 lists:all関数は true を返す。2つ目の[a,b,c,d,e,1]
は1つだけ整数が入っているので、false を返している。
any/2 関数
any(Pred, List) -> boolean()
Types
Pred = fun((Elem :: T) -> boolean()) List = [T] T = term()
リスト内の少なくとも1つの要素Elemに対して Pred(Elem) がtrueを返す場合、trueを返す。
> IsAtom = fun(X) -> is_atom(X) end. #Fun<erl_eval.6.99386804> > lists:any(IsAtom, [a,b,c,d,e]). true > lists:any(IsAtom, [a,b,c,1,2]). true > lists:any(IsAtom, [1,2,3,4,5]). false
第1引数は、リストの要素がatomかどうかを判定をする関数である。リスト内に少なくとも1つatomがあれば、trueを返している。すべて、atomでない場合は falseを返す。
append/1 関数
append(ListOfLists) -> List1
Types
ListOfLists = [List] List = List1 = [T] T = term()
ListOfListsのすべてのサブリストが追加されたリストを返す。
> List1 = [1,2,3]. [1,2,3] > List2 = [a,b]. [a,b] > List3 = [4,5,6]. [4,5,6] > lists:append([List1, List2, List3]). [1,2,3,a,b,4,5,6]
複数のリストをまとめて1つのリストにしたいときに使います。
append/2 関数
append(List1, List2) -> List3
Types
List1 = List2 = List3 = [T] T = term()
List1の要素とList2の要素から構成される新しいリストList3を返す。
> List1 = [1,2,3]. [1,2,3] > List2 = [a,b]. [a,b] > lists:append(List1, List2). [1,2,3,a,b]
2つのリストを1つのリストにする。Erlangの文字列の実体はリストなので、文字列の連結にも使える。
> lists:append("abc", "def"). "abcdef"
concat/1 関数
concat(Things) -> string()
Types
Things = [Thing] Thing = atom() | integer() | float() | string()
Thingsの要素のテキスト表現を連結します。 Thingsの要素は、原子、整数、浮動小数点数、または文字列のどれか。
> lists:concat([path,'/', to, "/", 1]). "path/to/1"
atomや数値をそのまま与えても文字列化した上で連結してくれる関数。文字列は文字のコードポイントのリストなので、このような関数が lists モジュールに含まれている。
delete/2
delete(Elem, List1) -> List2
Types
Elem = T List1 = List2 = [T] T = term()
Elem の要素がある場合に、List1 から Elem を削除したリストのコピーを返す。
>lists:delete(1, [1,2,3,4,5]). [2,3,4,5] > lists:delete({a, "Alice"}, [{a, "Alice"},{b, "Bob"}]). [{b,"Bob"}]
Elem は term() なので、{a, "Alice"}
のようなタプルでも要素と一致すれば、削除される。
droplast/1 関数
droplast(List) -> InitList
Types
List = [T, ...] InitList = [T] T = term()
リストの最後の要素を削除する。ただし、リストが空の場合は、function_clause で関数がクラッシュする。
> lists:droplast([a,b,c,d,e]). [a,b,c,d] > lists:droplast([a]). [] > lists:droplast([]). ** exception error: no function clause matching lists:droplast([]) (lists.erl, line 218)
try catch で囲むと、クラッシュエラーの理由が fanction_clause になっていることがわかる。
18> try lists:droplast([]) catch Type:Reason -> io:format("Type:~p Reason:~p~n",[Type,Reason]) end. Type:error Reason:function_clause ok
dropwhile/2 関数
dropwhile(Pred, List1) -> List2
Types
Pred = fun((Elem :: T) -> boolean()) List1 = List2 = [T] T = term()
Pred(Elem)が true を返す間、List1 から要素 Elem を削除し、残りのリストを返す。
19> IsAtom = fun(X) -> is_atom(X) end. #Fun<erl_eval.6.99386804> 20> lists:dropwhile(IsAtom, [a,b,c,d,e]). [] 21> lists:dropwhile(IsAtom, [a,b,c,1,2]). [1,2] 22> lists:dropwhile(IsAtom, [a,1,c,2,3]). [1,c,2,3] 23> lists:dropwhile(IsAtom, [1,2,3,4,5]). [1,2,3,4,5]
また IsAtom に 引数が atom かどうかをチェックする無名関数をバインドする。上記の例をみるとわかるように、リストの先頭の要素から順番に第1引数に指定した関数のチェックを行い、trueである限り削除する。途中で false になった場合、それ以降のリストのチェックは行われない。
duplicate/2 関数
duplicate(N, Elem) -> List
Types
N = integer() >= 0 Elem = T List = [T] T = term()
term() である Elem の N 個のコピーを含むリストを返す。
> lists:duplicate(5, a). [a,a,a,a,a] > lists:duplicate(5, {a, [{a, "Alice"}]}). [{a,[{a,"Alice"}]}, {a,[{a,"Alice"}]}, {a,[{a,"Alice"}]}, {a,[{a,"Alice"}]}, {a,[{a,"Alice"}]}]
このとき、Elem は Erlangで表現できるものであれば、どんなものでもコピーする。