# Array Expression array expression は、順序付きの値の列を表す。 ```dcdl [1, 2, 3] ["a", "b", "c"] ``` 配列リテラルは concrete value であり、要素型を揃える必要はない。 ```dcdl ["api", 8080, true] ``` ## Array constraint 配列制約は `[` の直後に ellipsis を置き、その後へ要素制約を記述する。 ```dcdl Names = [...String]; Ports = [...(Int & >= 1 & <= 65535)]; ``` `[...T]` は、すべての要素が `T` を満たす長さ 0 以上の配列を表す。 空配列は任意の配列制約を満たす。 ```dcdl [...String] & [] [...String] & ["api", "worker"] ``` 要素制約は object range にもできる。 右辺だけにある default 付き field は、配列へ制約を合成した時点では abstract のまま各要素に残る。 その配列を後から materialize した場合にだけ default が使われる。 ```dcdl 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 同士を連結する。 ```dcdl base = ["read", "write"]; extra = ["admin"]; roles = base ++ extra; ``` `roles` は以下と同じ値になる。 ```dcdl ["read", "write", "admin"] ``` `++` は配列要素を変換しない。 左辺の要素の後に右辺の要素が並ぶ。