今日はシーケンスです。シーケンスとはListみたいなもんです。ただ、Listとは違う特徴を持ってるのでしっかりそこらへんをおさえましょう。
使ってみよう
とりあえず使ってみないことにはどんなものかわかりません。シーケンスを生成して値を表示するだけのプログラムを書いてみます。
// 1〜5のシーケンス let s = seq { 1..5 } for i in s do printfn "%d" i printfn "-----------------------" // 1〜5を2乗したもの let s2 = seq { for i in 1..5 do yield i * i } for i in s2 do printfn "%d" i
実行すると以下のような結果になります。
1 2 3 4 5 ----------------------- 1 4 9 16 25
とりあえず、seq { なにか }のような形でシーケンスが作れてyield 値とやることでシーケンスの要素を返すような形です。ということなので、以下のような実装でもOKです。
let s = seq { printfn "Generate One" yield "One" printfn "Generate Two" yield "Two" printfn "Generate Three" yield "Three" } for i in s do printfn "%s" i for i in s do printfn "%s" i
実行すると以下のような結果になります。
Generate One One Generate Two Two Generate Three Three Generate One One Generate Two Two Generate Three Three
この結果をよくみるとシーケンスの特徴が見えてきます。シーケンスの返す値は、シーケンスを作成したときではなく、シーケンスから値を取り出す時に作られています。シーケンスを作成したタイミングで値が生成されている場合は以下のような実行結果になるはずですから
Generate One Generate Two Generate Three One Two Three One Two Three
しかも、2回ループを回したら2回値の生成処理が走ってることがわかります。これも特徴ですね。
さて、yieldで値を返せることがわかりました、あと、値が必要になったタイミングで値を作る処理が走ることもわかりました。次は、もう1つの値の返し方のyield!の動きを見てみようと思います。
let s = seq { yield 0 yield! [1;2;3] yield 4 } for i in s do printfn "%d" i
これを実行すると以下のようになります。
0 1 2 3 4
yieldが引数に渡された値をそのまま返すのに対してyield!は引数に渡された集合をバラしてからシーケンスの要素として返します。
因みにシーケンスは・・・
F#のシーケンスですが、結局のところ.NETのIEnumerable
シーケンスの便利メソッド
因みにシーケンスを操作するための色々な便利な関数達がSeqモジュールに定義されています。MSDNを見るのがいいです。
ちょっとだけ関数を使ってみます。
let s = seq { 1..100 } s |> // 偶数だけ抽出して Seq.filter (fun i -> i % 2 = 0) |> // 合計をとる Seq.sum |> // 印字 printfn "%d"
こんな風にパイプ演算子で繋いで色々やることで、LINQやってるみたいにサクサクと集合の処理を行うことが出来ます。
実行すると以下のようになります。
2550
あと、値が必要になったタイミングで値を取得するという特徴から無限のリストを扱うことが出来ます。
// 永遠に0,1,2,3,4...と値を返すシーケンス let s = seq { let i = ref 0 while true do yield !i i := !i + 1 } s |> // 最初の10個を飛ばして Seq.skip 10 |> // そのあとの10個を取り出して Seq.take 10 |> // 印字する Seq.iter (printfn "%d")
実行すると、ちゃんと値が表示されます。
10 11 12 13 14 15 16 17 18 19
いい感じですね。
過去記事
- 手軽なスクリプト言語としてのF#
- 手軽なスクリプト言語としてのF# その2
- 手軽なスクリプト言語としてのF# その3
- 手軽なスクリプト言語としてのF# その4
- 手軽なスクリプト言語としてのF# その5
- 手軽なスクリプト言語としてのF# その6
- 手軽なスクリプト言語としてのF# その7
- 手軽なスクリプト言語としてのF# その8「レコード」
- 手軽なスクリプト言語としてのF# その9「クラス」
- 手軽なスクリプト言語としてのF# その10「継承・アブストラクトクラス」
- 手軽なスクリプト言語としてのF# その11「インターフェースと演算子のオーバーロード」
- 手軽なスクリプト言語としてのF# その12「ラムダ式とイベント」
- 手軽なスクリプト言語としてのF# その13「オブジェクト初期化子みたいなの」
- 手軽なスクリプト言語としてのF# その14「合成演算子とパイプ演算子」
- 手軽なスクリプト言語としてのF# その15「WPFしてみた」
- 手軽なスクリプト言語としてのF# その16「総称型 ジェネリック」
- 手軽なスクリプト言語としてのF# その17「リスト」
- 手軽なスクリプト言語としてのF# その18「オプション型」
- 手軽なスクリプト言語としてのF# その19「参照型よりオプション型って安全?」
- 手軽なスクリプト言語としてのF# その20「パターンマッチ」
- 手軽なスクリプト言語としてのF# その21「再帰とループ」
- 手軽なスクリプト言語としてのF# その22「列挙型」
- 手軽なスクリプト言語としてのF# その23「アクティブパターン」
- F# + WPF + MVVM で足し算アプリ