Chains and Vectors
💡 お知らせ: このドキュメントはAIによって翻訳されています。表現に違和感がある場合は、原文(英語)を参照するか、翻訳にご協力ください。
Flix はイミュータブルな List に加えて、イミュータブルな Chain と Vector もサポートしています。
次の表は、list、chain、vector のあいだの性能上のトレードオフを示しています:
| 操作 \ 型 | List | Chain | Vector |
|---|---|---|---|
| 先頭要素の取得 | O(1) | O(n) | O(1) |
| 末尾要素の取得 | O(n) | O(n) | O(1) |
| インデックス指定の取得 | O(n) | O(n) | O(1) |
| Cons | O(1) | O(n) | O(n) |
| Append | O(n + m) | O(1) | O(n + m) |
List、Chain、Vector のどれを使うべきでしょうか?:
Listデータ構造は、シンプルでよく知られているため、デフォルトの選択肢になります。Vectorデータ構造は、コレクションのサイズが固定されている場合や、高速なランダムアクセスが必要な場合に最適な選択肢です。Chainデータ構造はあまり使われませんが、高速な append が必要な場合に真価を発揮します。
Chains
Chain[t] は、要素のイミュータブルな連結シーケンスです。
Chain[t] データ型は次のように定義されています:
enum Chain[t] {
case Empty
case One(t)
case Chain(Chain[t], Chain[t])
}
このデータ構造が O(1) の append をサポートするのは、Chain コンストラクタ(より適切には Chain.append)を使って、既存の2つの chain から新しい chain を構築できるためです。
chain は Chain.empty、Chain.singleton、Chain.cons、Chain.append を使って構築できます。
たとえば、次のように書けます:
let c = Chain.cons(1, Chain.empty());
println(c)
これはコンパイルして実行すると Chain#{1} を出力します。
Vectors
Vector[t] は、型 t の連続した要素からなる、イミュータブルで固定長のシーケンスです。
Flix は Vector リテラルをサポートしています。たとえば、次のように書けます:
Vector#{1, 2, 3}
これは、要素 1、2、3 を持つ長さ 3 の vector を作成します。
vector は Vector.get 操作による高速なランダムアクセスをサポートしています:
let v = Vector#{1, 2, 3};
println(Vector.get(2, v))
これはコンパイルして実行すると 3 を出力します。
警告: vector の範囲を超えたインデックスでアクセスすると、プログラムはパニックします。
vector は多くの操作をサポートしています。たとえば、vector に対して関数をマップできます:
let v = Vector#{1, 2, 3};
Vector.map(x -> x + 1, v)
これは Vector#{2, 3, 4} に評価されます。