Erlang をはじめよう その2
前回 - mog project: Getting Started with Erlang pt.1 の続き
CHAPTER 3: Atoms, Tuples, and Pattern Matching
アトム
アトムを利用したパターンマッチ、ブール値を示す特別なアトム
> hello. > F = (fun(apple, Num) -> 100 * Num; (banana, Num) -> 200 * Num end). > F(apple, 2). > F(banana, 3). > F(candy, 4). % error > 3<2. > 3>2. > 10 == 10. > true and true. > true or false. > false xor false. > not false.
ガード
when句、アンダースコアの利用
> Abs = (fun (Num) when Num =< 0 -> -Num; (Num) when Num > 0 -> Num end). > Abs(-10). > Abs(0). > Abs(3). > Abs = (fun (Num) when Num -Num; (Num) when Num >= 0 -> Num end). % error > Abs2 = (fun > (Num) when Num < 0 -> -Num; > (0) -> 0; > (Num) -> Num > end). > Abs2(-5). > _. > _ = 20. > _. > F = (fun(apple, Num) -> 100 * Num; (_, Num) -> 500 * Num end). > F(apple, 3). > F(candy, 10). > G = (fun(apple, Num) -> 100 * Num; (_, _) -> 1 end). > G(hello, world).
タプル
タプルの操作、パターンマッチでの利用
> {atom, 123, "string"}.
> T = {atom, 123, "string"}.
> element(2, T).
> setelement(2, T, 456).
> tuple_size(T).
> {A, B, C} = T.
> A.
> B.
> C.
> F = (fun ({apple, Num}) -> 100 * Num; ({banana, Num}) -> 200 * Num end).
> F({apple, 3}).
タプルを使った実装の隠蔽 (カプセル化)
-module(shop).
-export([buy/1]).
buy({Item, Num}) -> buy(Item, Num).
buy(apple, Num) when Num >= 0 -> 100 * Num;
buy(banana, Num) when Num >= 0 -> 200 * Num;
buy(_, Num) when Num >= 0 -> 500 * Num;
buy(_, _) -> 0.
> c(shop).
> shop:buy({apple, 3}).
> shop:buy({banana, 2}).
> shop:buy({candy, 1}).
> shop:buy({apple, -1}).
> shop:buy(apple, 3). % error
CHAPTER 4: Logic and Recursion
case 構成要素 (case construct)
case は値を返す。case 内部でガードを行うことも可能。
> F = fun (Item, Num) -> > case Item of > apple -> 100 * Num; > banana -> 200 * Num > end > end. > F(apple, 3). > G = fun (Item, Num) -> > X = case Item of > apple -> 100; > banana when Num >= 5 -> 198; > banana -> 200 > end, > X * Num > end. > G(banana, 3). > G(banana, 10).
if 構成要素 (if construct)
> F = fun (Item, Num) ->
> X = 100.
> if X >= 99 -> 'good' end.
> if X =< 99 -> 'good' end.
> F = fun(X) ->
> if
> X =< 99 -> io:format("X is less than ~w.~n", [100]);
> true -> true
> end
> end.
> F(10).
> F(100).
> A = 10.
> B = if A == 5 -> 100; true -> 20 end.
> B.
> BadFun = fun (X) ->
> if
> X < 0 -> Y = 1;
> X >= 0 -> Z = 2
> end,
> Y + Z
> end.
再帰
カウントダウン
-module(count).
-export([countdown/1]).
countdown(From) when From > 0 ->
io:format("~w!~n", [From]),
countdown(From - 1);
countdown(From) ->
io:format("blastoff!~n").
> c(count). > count:countdown(10).
階乗
-module(fact). -export([factorial/1]). factorial(N) when N =< 1 -> 1; factorial(N) -> N * factorial(N - 1).
> c(fact). > fact:factorial(10).
階乗 (アキュムレーター付き)
-module(fact). -export([factorial/1]). factorial(N) -> factorial(1, N, 1). factorial(Current, N, Result) when Current =< N -> factorial(Current + 1, N, Result * Current); factorial(Current, N, Result) -> Result.
> c(fact). > fact:factorial(10).
References