# 例 この章には、仕様を説明するための例を置く。 ## 基本的な設定スキーマ ```dcdl Host = IPv4Address; Port = Int & >= 1 & <= 65535; NarrowedPort = Port & > 443; MyConfig = { host = Host; port = NarrowedPort default 8080; feature_hoge = { enable = Bool default true; fuga = Int default 10; }; }; NewConfig = MyConfig & { host = "127.0.0.1"; port = 8000; }; disabled_config = NewConfig & { feature_hoge.enable = false; }; enabled_config = NewConfig; ``` ## 配列スキーマ ```dcdl Services = [...{ name = String; port = Int default 8080; }]; [ { name = "api"; }, { name = "worker"; port = 9000; }, ] as Services ``` 抽象配列には要素制約が必須である。 この例では、1 番目の要素の `port` は `8080` に materialize される。 ## 連想配列と範囲絞り込み ```dcdl Service = { port = Int; enabled = Bool default true; }; services = { api = { port = 8080; }; worker = { port = 8081; enabled = false; }; } as {...Service}; ``` `api` と `worker` は任意の key であり、それぞれの value は `Service` より狭い範囲へ絞り込まれる。 `as` の結果では `api.enabled` は abstract のまま残り、最終的に結果全体を materialize した時点で default の `true` が使われる。 ## 関数と制約 ```dcdl let Port = Int & >= 1 & <= 65535; add_offset = (base: Port, offset: Int) => base + offset; in add_offset(8000, 80) ``` 評価結果: ```text 8080 ``` ## match ```dcdl ( input_a: { hoge = Int & >= 0; }, input_b: { fuga = 20; } ) => let inputs = { a = input_a; b = input_b; }; in { foo = match inputs.a.hoge { >= 20: { value = 200; }; >= 10: { value = 100; }; _: { value = 300; }; }; } ``` `match` は上から順に評価されるため、広い条件より狭い条件を先に書く。 ## deep patch ```dcdl Base = { feature_hoge = { enable = Bool default true; fuga = Int default 10; }; }; Patched = Base // { feature_hoge.enable = false; }; ``` `Patched` は以下に相当する。 ```dcdl { feature_hoge = { enable = false; fuga = Int default 10; }; } ``` ## 循環 import ```dcdl # main.n { schema = { hoge = String; }; result = (import ./func.n)(schema); } ``` ```dcdl # func.n (input: (import ./main.n).schema) => { # ... } ``` `func.n` は `main.n` を import しているが、参照しているのは `main.schema` である。 `main.schema` が `main.result` に依存していなければ、この循環 import は成立する。