学習の記録−8

配列の定義

リスト[]の代わりに[||]と書く。List.toArray関数を使えばリストから生成することも可能。

> let x = [|1..3|];;

val x : int [] = [|1; 2; 3|]
> List.toArray [1..3];;
val it : int [] = [|1; 2; 3|]

配列のアクセス

Listと違ってランダムアクセスが可能。mutableなんで破壊的代入が可能。要素のアクセスにはインデクサー.[]を使うか、Array.getを用いる。インデックスのスタートは0.

> let x = [|1..3|];;

val x : int [] = [|1; 2; 3|]

> x.[2];;
val it : int = 3
> x.[2] <- 100;;
val it : unit = ()
> x;;
val it : int [] = [|1; 2; 100|]
> Array.get x 0;;
val it : int = 1
> Array.set x 0 55;;
val it : unit = ()
> x;;
val it : int [] = [|55; 2; 100|]

シーケンス(リスト、配列等のコレクションの抽象化)

seq{}で定義する。内包表記ももちろん可能。シーケンスは遅延実行される、pythonでいうxrange的なもんか。

> seq{1..3};;
val it : seq<int> = seq [1; 2; 3]
> seq{ for i in 0..9 -> i * i};;
val it : seq<int> = seq [0; 1; 4; 9; ...]

リストの抽象化したやつなんで、seqを引数に取る関数は配列・リストも適用できる

> let x = [1..5];;

val x : int list = [1; 2; 3; 4; 5]

> Seq.map (fun n -> n*2) x;;
val it : seq<int> = seq [2; 4; 6; 8; ...]

関数もいろいろあるようだ。シーケンスを生成するunfold関数はうまく使いこなしたい。シーケンスを一回評価させた後はメモリに乗っけるようにも設定できてSeq.cache関数を使えばよいらしい。

> let x = [0;0;1;1;1;2;3;4;5;5;6];;

val x : int list = [0; 0; 1; 1; 1; 2; 3; 4; 5; 5; 6]

> Seq.distinct x;;
val it : seq<int> = seq [0; 1; 2; 3; ...]
> Seq.groupBy id x;;
val it : seq<int * seq<int>> =
  seq [(0, seq [0; 0]); (1, seq [1; 1; 1]); (2, seq [2]); (3, seq [3]); ...]
> Seq.countBy id x;;
val it : seq<int * int> = seq [(0, 2); (1, 3); (2, 1); (3, 1); ...]
> Seq.unfold (fun n -> if n <= 9 then Some (n * n, n + 2) else None) 0;;
val it : seq<int> = seq [0; 4; 16; 36; ...]

辞書(Map)

デフォルトで辞書型も組み込まれている。キーで値を検索するにはMap.tryFind、キーと値からキーを検索するにはtryFindKey関数を使う

> let x = Map.ofSeq(seq{for i in 0..3 -> i, i * i});;

val x : Map<int,int> = map [(0, 0); (1, 1); (2, 4); (3, 9)]
> Map.tryFind 1 x;;
val it : int option = Some 1
> Map.tryFind 2 x;;
val it : int option = Some 4
> Map.tryFindKey (fun key value -> key = 2 && value = 4) x;;
val it : int option = Some 2