Typecheck
Reusable typeCheck handlers. Use policy.<name> for the canonical surface; legacy strict/collecting/logging attributes are preserved for back-compat.
collecting
policy.collecting: accumulates every failing typeCheck into state as a list of { context, typeName, actual, message, path, reason }.
Collecting typeCheck handler: accumulates errors in state.
Resumes with true on success, false on failure (computation continues).
State shape: list of { context, typeName, actual, message, path, reason }
Initial state: []
firstN
policy.firstN N: bounded-collection handler keeping up to N failures, then setting aborted = true and dropping the rest. State stays bounded.
firstN : Int -> Handler
Bounded-collection handler: collects up to N failures, then drops the rest.
Useful for early-termination policies where the consumer only needs
a handful of representative errors. After the Nth failure, aborted
flips true and subsequent failures are silently dropped (state size
stays bounded at N entries).
State shape: { collected :: [errorRecord]; aborted :: Bool; }
Initial state: { collected = []; aborted = false; }
logging
policy.logging: records every typeCheck (pass and fail) in state with passed boolean; useful for tracing without aborting computation.
Logging typeCheck handler: records every check (pass or fail) in state. Always resumes with the actual check result (boolean).
State shape: list of { context, typeName, passed, path, reason }
Initial state: []
policy
policy: canonical grouped surface for typecheck handlers.
Grouped strict/collecting/logging/firstN/summarize/pretty handlers.
pretty
policy.pretty cfg: emits one pre-formatted [reason] expected T at <loc>, got <actualType> line per failure; renders the Position-list path with per-segment separators.
pretty : { sourceMap? } -> Handler
Display-rendering handler: emits one pre-formatted line per failure.
Renders the blame location by concatenating each Position's
segment field (.field, [i], #Tag carry their own
separator). Falls back to context when the path is empty.
Each line is shaped:
[reason] expected typeName at
cfg.sourceMap is reserved for future source-span annotation; not
consumed yet.
State shape: [String] (one entry per failure; consumer joins with
newline for display).
Initial state: []
strict
policy.strict: throws on the first failing typeCheck via builtins.throw; resumes with true on success. Halts evaluation on error.
Strict typeCheck handler: throws on first type error. Resumes with true on success (check passed).
Use when type errors should halt evaluation immediately. State: unused (pass null).
summarize
policy.summarize: bounded-memory grouping by reason; tracks counts per reason plus pass/fail totals. State is O(K) in distinct reasons, not O(N).
Bounded-memory grouping handler: counts failures by reason, drops
per-failure data (value/path/context/message) so memory stays O(K)
in the number of distinct reasons rather than O(N) in the number
of effects.
Use for high-volume validation where individual error records would blow up state — only the aggregate matters.
State shape: { byReason :: { <reason> = Int; ... }; passed :: Int; failed :: Int; }
Initial state: { byReason = {}; passed = 0; failed = 0; }