effectは「何がいつ確定するか」で三つに分かれる
CarinaのplanはApplicative的な静的グラフに近い。VPCとSubnetの依存はapply前に分かり、分からないのはVPCのIDという値だけである。だがそれだけでは説明できないeffectが現実にある。effectを「何がいつ確定するか」で並べると三つになる。
| 種類 | plan時に分かる | apply時に分かる | 例 |
|---|---|---|---|
| 静的に確定 | 構造も値も | — | 固定のCIDRを持つVPC |
| 値だけ後で確定 | 構造(個数・依存) | 属性値 | vpc_id = vpc.vpc_idのSubnet |
| 個数が後で確定 | ループの本体 | 繰り返し回数 | 証明書の検証オプションごとに作るDNSレコード |
三つ目の例はcarina#3589にある。
let validation_records = for opt in cert.domain_validation_options {
aws.route53.RecordSet {
hosted_zone_id = zone_id
name = opt.resource_record.name
...
}
}
ACM証明書を作るまでdomain_validation_optionsの要素数が分からないので、作るレコードの数もapplyまで決まらない。CarinaはこれをDeferredCreateというeffectとして扱う。#3589は、このdeferredな作成がplanの木と集計で+として数えられず、同じ系列の古い要素の-だけが目立って「削除だけのplan」に見えた、という報告である(2026-06-21にクローズ)。
Monadへ行かずに済む理由
三つ目はgraph形状がapply時に決まるので、一見Monad的である。だが自由ではない。ループの本体はplan時に分かっていて、決まらないのは回数だけである。前のeffectの結果を見て、まったく別の種類のeffectを作るわけではない。
だから「完全に静的」と「任意の動的生成」の間に段を一つ置けば足りる。この段のeffectも、planに「この形のものが後でN個作られる」と書ける。何が作られうるかは事前に読める。モノイドとモナドの対比はデプロイ計画がモノイドかモナドかで見通しが決まる、graph形状と属性値の区別は予測可能性はgraph形状と属性値の二側面を持つにある。
表示の問題として出てくる
#3589が示すように、この段のeffectは型より先にplanの表示で問題になる。予測可能性はplanを読む人のためのものなので、「後でN個」を+として数えないと、構造上は予測可能でも人には予測できない。IaCではIRダンプが一級の製品機能である Unknownは二段階の間に開いた窓である
根拠の確度
#3589の内容とDSL例はissue本文から写した。DeferredCreate / DeferredReplaceがEffectの変種であることはcarina main 273a2520で確認した。#3589の修正後にplan表示がどうなったかは確認していない(要確認)。三分類と「回数だけが決まらないのでMonadまで行かない」という整理は、ChatGPTとの対話をもとにした解釈である。