forループ
ここでは反復(forループ)について説明します。
forを用いることで、
同じ処理を繰り返すことや、少しずつ動作を変えながら繰り返し処理する
ようなことをプログラム出来ます。
単純なループなら、10万回程度は余裕で処理出来ます。
やはり、こういう数の力に頼れることは
プログラムのメリットですね。
forの構文は次の通りです。
- forループ
- for式1 := for 識別子 = 式1 to 式2 do 式3 done
for式2 := for パターン in 式4 do 式5 done
軽量構文ではそれぞれの構文でdoneを省略できます。
for式1はC言語風のループで、for式2はいわゆるforeachループです
for式2のことを、F#ではenumerable for loopと呼びます(F#4.1 spec 6)
for式1は、ループ変数となる識別子を式1で初期化し、
識別子が式2に等しくなるまで式3を繰り返します。
C言語風forループ
for i=0 to 5 do printfn "%d" i done;;
C言語風forループ(軽量構文)
for i=0 to 5 do printfn "%d" i
これは、0から5までの6つの値を標準出力に表示します。
(標準出力というのは、デフォルトの出力先のことで
通常はコンソール(ディスプレイ画面)になります)
for式2では、式4にある個々の要素をパターンに束縛し、
式5を実行します。この構文は非常に強力です。
foreach風ループ
for i in [1;2;3;4;5;] do printfn "%d" i done;;
for i in [|1;2;3;4;5;|] do printfn "%d" i done;;
for i in ["abc";"def";"ghi";] do printfn "%s" i done;;
for (a,b) in [("melon","fruit");("watermelon","vegetable")] do printfn "%s" (a + " is " + b); done;;
foreach風ループ(軽量構文)
for i in [1;2;3;4;5;] do printfn "%d" i
for i in [|1;2;3;4;5;|] do printfn "%d" i
for i in ["abc";"def";"ghi";] do printfn "%s" i
for (a,b) in [("melon","fruit");("watermelon","vegetable")] do printfn "%s" (a + " is " + b)
これは、リストや配列の中身をforeach風のfor文で出力したプログラムです。
リストの範囲外をアクセスする、といったことが起こらないため
リストや配列を対象にしている場合はC言語風ループよりも
こちらのほうが優れています。
printfnに渡す文字列に%dと書くと数値を、%sと書くと文字列を受け取って表示するようになります。
複数回書いた場合には複数回書いただけの引数を受け取るようになります。
この例の通り、パターンの箇所には配列風のものなら何でもループできます。
これにはリスト、シーケンス、配列、セット、マップなどが含まれます。
より正確には、次のパターンに当てはまるものになります。参考(
MSのドキュメント)
・System.Collections.IEnumerable を実装する任意の型
最初の例はリストなので、;で区切られた各要素が変数iに束縛されて
式が実行されます。
最後の例はタプルのリストに対するループで、
パターンマッチという機能を利用しています。
最初の要素("melon","fruit"))と(a,b)を比べて、
aに"melon",bに"fruit"を割り当てるという具合に
各要素に対して処理を行っています。
より詳しくは、パターンマッチの章で説明します。
.Net Frameworkのコレクションは(IEnumerableを実装しているため)
この形式のforループを使用すれば
イテレーション(1個ずつ中身をたどること)できます。
また、forループはループ処理のみでなく
ループの個々の結果をリストに保持することができます。
また、以下の->という記号はyieldと読みます。
foreach風ループその2
> [1..3];;
val it : int list = [1; 2; 3]
> [for i in [1..3] -> i*2];;
val it : int list = [2; 4; 6]
> [for i in [1..3] -> [for j in [2..4] -> (i,j)]];;
val it : (int * int) list list
= [[(1, 2); (1, 3); (1, 4)]; [(2, 2); (2, 3); (2, 4)];
[(3, 2); (3, 3); (3, 4)]]
F#では便利な記法として
[a..b]といった記述で連続した数値のリストを作ることができます。
この例ではyield機能を用いて、
[1..3]のリストのそれぞれを2倍するプログラムと
[1..3]、[2..4]のリストの順列組み合わせを出力するプログラムを記述しています。
実は、ここまで学んだことだけで
1967年、エドガー・ダイクストラによって提唱された
構造化プログラミングの構成要素である
「順次(順番に実行)」「反復(for)」「選択(if)」を
実現するための制御構造を学ぶことができました。
といっても、実用的にプログラムを書くには
これから先に説明する
データ構造について学んで行く必要があります。