Decodal/doc/manual/souce/language/examples.md
2026-06-16 01:27:54 +09:00

2.1 KiB

この章には、仕様を説明するための例を置く。

基本的な設定スキーマ

rec {
    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;

関数と文字列生成

let
    maybe_hw = String & /Hello! .*/;
    part = {
        greet = String;
        target = String;
    };
    mk_hw = (part: part) =>
        maybe_hw & "${part.greet}! ${part.target}";
in
    mk_hw({
        greet = "Hello";
        target = "World";
    })

評価結果:

"Hello! World"

match

(
    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

Base = {
    feature_hoge = {
        enable = Bool default true;
        fuga = Int default 10;
    };
};

Patched = Base // {
    feature_hoge.enable = false;
};

Patched は以下に相当する。

{
    feature_hoge = {
        enable = false;
        fuga = Int default 10;
    };
}

循環 import

# main.n
{
    schema = {
        hoge = String;
    };

    result = (import ./func.n)(schema);
}
# func.n
(input: (import ./main.n).schema) =>
{
    # ...
}

func.nmain.n を import しているが、参照しているのは main.schema である。 main.schemamain.result に依存していなければ、この循環 import は成立する。