学習の記録−7
リスト
F#でのリスト、以下のように書く。List.headで頭、List.tailで頭以外の要素を取得できる。
> let lst = 1::2::3::[];; val lst : int list = [1; 2; 3] > List.head lst;; val it : int = 1 > List.tail lst;; val it : int list = [2; 3] > let f lst = match lst with | [] -> "Empty" | _::_ -> "Exists" ;; val f : 'a list -> string > f lst;; val it : string = "Exists"
パターンマッチで使用している_::_は「コンス パターン」というものらしい。パターンの一覧はF#入門でまとめられているのが便利なので、これを参照するのがいい。
リスト内包表記
こんな書き方もできるらしい。
open System let f x = [for i in 1..10 do yield x * i] let g x = [for i in 1..10 -> x * i] Console.WriteLine (f 1);; Console.WriteLine (g 1);;
foldはreduceをパワーアップさせたもの(初期値指定が可能)
こんな感じで「文中にある母音の数を数える」コードも簡単にかける。
open System let countVowels (str : string) = let charList = List.ofSeq str let addFunc (As, Es, Is, Os, Us) letter = if letter = 'a' then (As + 1, Es, Is, Os, Us) elif letter = 'e' then (As, Es + 1, Is, Os, Us) elif letter = 'i' then (As, Es, Is + 1, Os, Us) elif letter = 'o' then (As, Es, Is, Os + 1, Us) elif letter = 'u' then (As, Es, Is, Os, Us + 1) else (As, Es, Is, Os, Us) List.fold addFunc (0, 0, 0, 0, 0) charList;; Console.Write(countVowels "The quick brown fox jumps over the lazy dog");;
リストの結合
List.append関数使うか、@演算子使うか。
> [1..3]@[4..7];; val it : int list = [1; 2; 3; 4; 5; 6; 7] > List.append [1..3] [4..7];; val it : int list = [1; 2; 3; 4; 5; 6; 7]
リストの部分集合抽出(filter, partition)
List.filterは該当部分のみを抽出、List.partition関数はだめだったケースもまとめて返してくれる。
> let x = [1..10];; val x : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] > List.filter (fun n -> abs n > 5) x;; val it : int list = [6; 7; 8; 9; 10] > List.partition (fun n -> abs n > 5) x;; val it : int list * int list = ([6; 7; 8; 9; 10], [1; 2; 3; 4; 5])