無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

「|」演算子、ifとcaseでの条件分岐

Getting Started With Erlang2.10 More About Lists2.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 ).

実行結果は長いので省略。

  • 余りを取得する演算子を"%"にしていてはまった。正解は"rem"でした。%はコメントの開始。
  • 最初「fizzbuzz(101) -> ok;」を書くのを忘れて無限ループした(お約束)。

ガード条件でも似たようなことができそうなんだけど、棲み分けはどうなっているんだろう・・。

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 ).