Files
Decodal/doc/manual/source/jp/language/expression/array.md
T

2.0 KiB

Array Expression

array expression は、順序付きの値の列を表す。

[1, 2, 3]
["a", "b", "c"]

配列リテラルは concrete value であり、要素型を揃える必要はない。

["api", 8080, true]

Array constraint

配列制約は [ の直後に ellipsis を置き、その後へ要素制約を記述する。

Names = [...String];
Ports = [...(Int & >= 1 & <= 65535)];

[...T] は、すべての要素が T を満たす長さ 0 以上の配列を表す。 空配列は任意の配列制約を満たす。

[...String] & []
[...String] & ["api", "worker"]

要素制約は object range にもできる。 右辺だけにある default 付き field は、配列へ制約を合成した時点では abstract のまま各要素に残る。 その配列を後から materialize した場合にだけ default が使われる。

Services = [...{
    name = String;
    enabled = Bool default true;
}];

Services & [{ name = "api"; }]

配列制約を concrete array に適用すると、各要素は要素 range に対して as と同じ規則で絞り込まれる。 object の要素 range では左辺にしかない field がエラーになり、右辺にしかない field は abstract のまま残る。

要素制約のない抽象配列型は提供しない。 旧来の Array primitive type は使用できず、[...T]T は必須である。 [String] は配列制約ではなく、未解決の String 制約を 1 要素に持つ concrete array になる。 配列制約は要素範囲だけを表す。長さ制約、位置別の tuple 制約、unique 制約は持たない。

Array concat

++ は concrete array 同士を連結する。

base = ["read", "write"];
extra = ["admin"];
roles = base ++ extra;

roles は以下と同じ値になる。

["read", "write", "admin"]

++ は配列要素を変換しない。 左辺の要素の後に右辺の要素が並ぶ。