Scope
Computation-scoped handlers via effect rotation.
handlersFromAttrs
Helper to transform an attrset into named handlers.
If attrValue is a function { param, state } it is used directly as handler;
If attrValue is a function, resume is f param and preserves state;
Otherwise a constant handler always resumes with attrValue, preserving state.
provide
Install handlers for a computation's dynamic extent without touching state. Unhandled effects rotate outward; outer handler state mutations survive unaffected.
This is the reader/val handler pattern (Koka's val, Haskell's
runReader, Scheme's parameterize) — use it when handlers are
stateless (resume with a constant, pass state through).
For handlers that need their own state, use scope.run or
scope.stateful instead.
scope.provide : handlers -> Computation a -> Computation a
run
Run a computation with scoped handlers. Effects matching handlers
are handled inside the scope. Unknown effects rotate outward.
The scope's internal state is hidden — caller sees only the body's value.
scope.run : { handlers, state? } -> Computation a -> Computation a
runWith
Like scope.run but exposes the scope's final state alongside the value.
scope.runWith : { handlers, state? } -> Computation a -> Computation { value, state }
stateful
Run a computation with scoped handlers while preserving state around effect rotation.
scope : handlers -> Computation a -> Computation a
val
Provide constant values as named effect handlers for a computation's dynamic extent. Each key in the bindings attrset becomes an effect that resumes with the corresponding value. Built on scope.provide via handlersFromAttrs.
Named after Koka's val effect handler. For the traditional
single-environment reader (ask/asks/local), see fx.effects.reader.
scope.val : AttrSet -> Computation a -> Computation a