F#のlistは、0個以上の値からなるイミュータブルなコレクションです。配列内の値は、すべて同じ型でなければなりません。配列はイミュータブルなので、一度作成されると、その値を変更することはできません。配列を変更するように見える関数や演算子(要素の追加など)も、実際には新しい配列を返します。
配列は次のように定義できます。
let empty = []
let singleValue = [5]
let threeValues = ["a"; "b"; "c"]
配列に要素を追加する最も一般的な方法は、::(cons)演算子を使うことです。
let twoToFour = [2; 3; 4]
let oneToFour = 1 :: twoToFour
// => [1; 2; 3; 4]
F#の配列には、先頭(最初の要素)と_末尾_(最初の要素より後ろのすべての要素)があります。配列の末尾は、それ自体も配列です。
配列は、Listモジュールで定義された関数や演算子を使って操作するか、_配列_パターンと_cons_パターンを使ったパターンマッチングで手動で操作します。
let describe list =
match list with
| [] -> "Empty list"
| head::tail -> sprintf "Non-empty list with head: %d" head
describe [] // => "Empty list"
describe [1] // => "Non-empty with head: 1"
describe [5; 7; 9] // => "Non-empty with head: 5"
パターンマッチングでは、値を_破棄_することもできます。特定のケースで値を気にしないとき(つまり、その値を_使う_つもりがないとき)は、アンダースコア('_')を使ってそれを表すことができます。
let describe list =
match list with
| [] -> "Empty list"
| [x] -> "List with one item"
| [_; y] -> "List with two items (first item ignored)"
| _ -> "List with many items (all items ignored)"
describe [] // => "Empty list"
describe [1] // => "List with one item"
describe [5; 7] // => "List with two items (first item ignored)"
describe [5; 7; 9] // => "List with many items (all items ignored)"
'_'はパターンマッチングで必ず_最後_に置きます。他のどのケースにも_一致しない_値はすべて、このケースで処理されます。
この演習では、Exercismで学びたいプログラミング言語の配列を管理するコードを書きます。
6つのタスクがあり、いずれも配列を扱います。
学びたい言語を管理するには、新しい配列を作成する必要があります。新しくて空の配列を保持するnewList束縛を定義します。
newList
// => []
現在、学びたい言語が書かれた紙が1枚あります。F#、Clojure、Haskellです。この配列を表すexistingList束縛を定義します。
existingList
// => ["F#"; "Clojure"; "Haskell"]
Exercismを探検してもっと面白い言語を見つけたら、それを配列に追加したくなります。配列の先頭に新しい言語を追加するaddLanguage関数を実装します。
addLanguage "TypeScript" ["JavaScript"; "CoffeeScript"]
// => ["TypeScript"; "JavaScript"; "CoffeeScript"]
言語を1つずつ数えるのは面倒です。配列にある言語の数を数えるcountLanguages関数を実装します。
countLanguages ["C#"; "Racket"; "Rust"; "Ruby"]
// => 4
あるとき、配列が実は逆順に並んでいることに気づきます! 配列を逆にするreverseList関数を実装します。
reverseList ["Prolog"; "C"; "Idris"; "Assembly"]
// => ["Assembly"; "Idris"; "C"; "Prolog"]
どの言語も大好きですが、F#は心の中で特別な存在です。そのため、次のような配列には、とてもわくわくします。
配列がエキサイティングかどうかを確認するexcitingList関数を実装します。
excitingList ["Nim"; "F#"]
// => true