Add associative map constraints and range refinement
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
| `&` | `lhs & rhs` | composition | value / constraint / object | constraint-preserving composition |
|
||||
| `//` | `lhs // rhs` | patch | object / value | right-biased structural patch |
|
||||
| `default` | `base default fallback` | default | abstract value | materialization fallback |
|
||||
| `as` | `narrower as wider` | range refinement | value / constraint / structure | narrower result plus untouched right-only ranges |
|
||||
|
||||
`concrete scalar` は `String`、`Bool`、`Int`、`Float` を指す。
|
||||
|
||||
@@ -48,6 +49,7 @@
|
||||
9. `&`
|
||||
10. `//`
|
||||
11. `default`
|
||||
12. `as`
|
||||
|
||||
同じ優先順位の二項演算子は左結合である。
|
||||
`default` は右結合である。
|
||||
@@ -91,6 +93,7 @@ A & B
|
||||
- 両方が異なる具体値なら conflict になる。
|
||||
- 両方が object なら、フィールドごとに合成する。
|
||||
- 同じフィールドが両方にある場合、そのフィールド値を `&` で合成する。
|
||||
- 片方にしかないフィールドは、そのまま結果に保持する。
|
||||
- 矛盾が発生した場合はエラーになる。
|
||||
|
||||
例:
|
||||
@@ -188,12 +191,44 @@ object field 全体を特別に置き換えるための `replace(...)` 構文や
|
||||
|
||||
object 全体を別構造にしたい場合は、patch 対象より外側で値を作り直す。
|
||||
|
||||
## `&` と `//` の使い分け
|
||||
## `as`: range refinement
|
||||
|
||||
`&` は制約を満たす具体化に使う。
|
||||
`as` は左辺が右辺より具体的で狭い範囲であることを確認する、非対称な絞り込み演算子である。
|
||||
|
||||
```dcdl
|
||||
ValidConfig = MyConfig & {
|
||||
Refined = {
|
||||
port = 8000;
|
||||
} as {
|
||||
port = Int & >= 1 & <= 65535;
|
||||
host = String;
|
||||
enabled = Bool default true;
|
||||
};
|
||||
```
|
||||
|
||||
`port` は左辺の `8000` に具体化される。
|
||||
右辺にしかない `host` と `enabled` は abstract のまま結果へ残る。default の有無は、右辺だけの field を保持するかどうかに影響しない。
|
||||
`as` 自体は default を選択せず、後から結果を materialize した場合だけ通常の default 規則が働く。
|
||||
|
||||
左辺にしかない object field は右辺の field domain 外なのでエラーになる。
|
||||
両側にある nested object、array constraint、map constraint は同じ規則で再帰的に絞り込む。
|
||||
|
||||
abstract range 同士も包含を確認できる。
|
||||
|
||||
```dcdl
|
||||
Int & > 10 as Int & > 0 # 成功し、Int & > 10 を返す
|
||||
Int as Int & > 0 # 失敗
|
||||
```
|
||||
|
||||
`&` は対称な合成であり、片方だけにある object field を保持する。
|
||||
したがって、左右に方向を持つ絞り込みを `&` で代用しない。
|
||||
詳細は [Range Refinement](./expression/ascription.md) を参照する。
|
||||
|
||||
## `&`、`//`、`as` の使い分け
|
||||
|
||||
`&` は制約や部分構造を失わず、対称に合成する。
|
||||
|
||||
```dcdl
|
||||
Combined = MyConfig & {
|
||||
port = 8000;
|
||||
};
|
||||
```
|
||||
@@ -208,3 +243,9 @@ ModifiedSchema = MyConfig // {
|
||||
|
||||
`//` は右辺優先の patch であり、左辺の制約を常に保持するとは限らない。
|
||||
制約を保持したい場合は `&` を使う。
|
||||
|
||||
左辺が右辺より狭いことを検証しながら合成する場合は `as` を使う。
|
||||
|
||||
```dcdl
|
||||
RefinedConfig = NarrowConfig as WideConfig;
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user