「|」演算子、ifとcaseでの条件分岐
Getting Started With Erlangの2.10 More About Listsと2.11 If and Caseを読みました。
「|」演算子を使った先頭要素の取得とリストの結合
「|」演算子でListの先頭要素を取得することができます。また、リストに要素を追加することができます。
- 「[HEAD|REST]」とした場合、HEAD変数は先頭要素、REST変数は残りの要素のリストとなります。
- さらに「NEW_LIST = [ mii | REST ].」といった感じで、要素を追加したリストを生成できます。
リストへの要素追加のサンプルです。配列の指定要素の前に要素を挿入します。
-module(insert). -export([insert/3]). % 指定した要素の前に要素を挿入する。 % マッチする要素がなければ末尾に追加する。 insert( [], TARGET, ITEM ) -> [ITEM]; insert( [HEAD|REST], TARGET, ITEM ) when TARGET == HEAD -> [ ITEM , HEAD | REST ]; % [LIST1|LIST2]でリストを連結できる。 insert( [HEAD|REST], TARGET, ITEM ) -> [ HEAD | insert( REST, TARGET, ITEM )].
実行結果です。
7> insert:insert([mii,tora,kuro], tora, shiro). [mii,shiro,tora,kuro] 8> insert:insert([mii,tora,kuro], mii, shiro). [shiro,mii,tora,kuro] 9> insert:insert([mii,tora,kuro], kuro, shiro). [mii,tora,shiro,kuro] 10> insert:insert([mii,tora,kuro], foo, shiro). [mii,tora,kuro,shiro]
なお、listsモジュールにリストを操作するための関数が用意されています。再発明してしまう前にチェック!
ifでの条件分岐
ifで条件分岐が作成できます。形式は次の通り
if <条件1> -> <処理>; <条件2> -> <処理>; <条件3> -> <処理> % 最後の処理のあとには ";"が付かない! end
- 条件の部分には「HOGE == 1」のような式が使えます。
- 処理の部分には任意の処理を書きます。条件にマッチした場合のみ、それに続く処理が実行されます。
- 処理のあとにさらに条件が続く場合は";"を付けます。
- 条件の終わりの場合は何も付けません。
- if文自体の戻り値は実行された処理の戻り値となります。
- どの条件にもマッチしなかった場合、エラー(!)になります。
- 「else」はありません。「true -> <処理>」みたいなのを最後に付けて代用するとのこと。
ifでの条件分岐のサンプル。FizzBuzzです。
-module(fizzbuzz). -export([fizzbuzz/0]). % 1から100までの数をプリントするプログラムを書け。 % ただし3の倍数のときは数の代わりに「Fizz」と、 % 5の倍数のときは「Buzz」とプリントし、 % 3と5両方の倍数の場合には「FizzBuzz」とプリントすること。 fizzbuzz() -> fizzbuzz(1). fizzbuzz(101) -> ok; fizzbuzz(I) -> if I rem 15 == 0 -> io:format( "FizzBuzz~n", [] ); I rem 3 == 0 -> io:format( "Fizz~n", [] ); I rem 5 == 0 -> io:format( "Buzz~n", [] ); true -> io:format( "~w~n", [I] ) end, fizzbuzz( I+1 ).
実行結果は長いので省略。
ガード条件でも似たようなことができそうなんだけど、棲み分けはどうなっているんだろう・・。
caseでの条件分岐
caseでも条件分岐することができます。形式は次の通り
case <評価式> of <パターン1> -> <処理>; <パターン2> -> <処理>; <パターン3> -> <処理> % 最後の処理のあとには ";"が付かない! end
- だいたい見ての通りです。評価式の値がパターンにマッチした場合、それに続く処理が実行されます。
- case文自体の戻り値は実行された処理の戻り値となります。
- どの条件にもマッチしなかった場合、エラー(!)になります。
- 条件にマッチしなかった場合に実行される処理の指定(javaのdefaultみたいなの)はないようです。ifのように「true -> ...」でも代用できないので注意。
FizzBuzzのCase版です。
-module(fizzbuzz2). -export([fizzbuzz/0]). % 1から100までの数をプリントするプログラムを書け。 % ただし3の倍数のときは数の代わりに「Fizz」と、 % 5の倍数のときは「Buzz」とプリントし、 % 3と5両方の倍数の場合には「FizzBuzz」とプリントすること。 fizzbuzz() -> fizzbuzz(1). fizzbuzz(101) -> ok; fizzbuzz(I) -> case I rem 15 of 0 -> io:format( "FizzBuzz~n", [] ); 1 -> io:format( "~w~n", [I] ); 2 -> io:format( "~w~n", [I] ); 3 -> io:format( "Fizz~n", [] ); 4 -> io:format( "~w~n", [I] ); 5 -> io:format( "Buzz~n", [] ); 6 -> io:format( "Fizz~n", [] ); 7 -> io:format( "~w~n", [I] ); 8 -> io:format( "~w~n", [I] ); 9 -> io:format( "Fizz~n", [] ); 10 -> io:format( "Buzz~n", [] ); 11 -> io:format( "~w~n", [I] ); 12 -> io:format( "Fizz~n", [] ); 13 -> io:format( "~w~n", [I] ); 14 -> io:format( "~w~n", [I] ) end, fizzbuzz( I+1 ).