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

2.3 KiB

materialize とエラー

通常の評価では、制約や default を含む中間値が残ることがある。 外部へデータとして出力する段階では、materialize を行う。

materialize の責務

materialize は以下を行う。

  • 必要なフィールドを評価する。
  • 明示値がない abstract value に default を適用する。
  • 採用された値が制約を満たすか検証する。
  • default を持たない未解決の abstract value をエラーにする。
  • 未適用の関数など、データとして出力できない値をエラーにする。

MyConfig = {
    host = String;
    port = Int default 8080;
};

MyConfig を materialize すると、host は具体値も default もないためエラーになる。 port8080 が採用される。

Config = MyConfig & {
    host = "localhost";
};

Config を materialize すると以下になる。

{
    host = "localhost";
    port = 8080;
}

default の適用

default は materialize 時にのみ fallback として採用される。

Abstract {
  constraints: [Int]
  default: 8080
}

この abstract value を materialize すると、8080 が採用され、Int を満たすか検証される。

明示値がある場合、default は採用しない。 明示値は concrete value として表現され、default を保持しない。

Concrete(Int(9000))

この値の最終値は 9000 である。

エラー分類

代表的なエラー:

  • 構文エラー
  • 未定義識別子
  • 型不一致
  • 制約違反
  • & の conflict
  • default の conflict
  • 循環依存
  • import 失敗
  • match の非網羅による失敗
  • materialize 不能な値の出力

match の失敗

match に fallback 分岐がなく、どの分岐にも一致しなかった場合はエラーになる。

match value {
    >= 10: "large";
}

value10 未満であれば失敗する。

エラーは値ではない

エラーは runtime value ではなく diagnostic として扱う。 通常の式はエラー内容に基づいて分岐できない。

汎用 try / catch は core には含めない。 fallback は defaultmatch、および将来的な optional import / optional field access のような限定された仕組みで表現する。