fp.effects¶
Reader, State and Writer describe computations that read an environment, pass
state between steps or accumulate a log. Compose them with the operations of
fp.algebra, and combine effects with monad transformers such as
ResultT and StateT. The example below shows how transformer order determines
whether a failed computation returns its final state.
Start with the effects tutorial for standalone Reader, State and Writer programs, deferred evaluation and callback ownership.
Reader, State and Writer computations and the OptionalT and ResultT layers, over any base Monad.
| Family | Value | Additional operations |
|---|---|---|
ReaderT[M, R] |
A ReaderAction: borrows R when run, returns M's carrier |
action, run, lift, ask, local |
StateT[M, S] |
A StateAction: consumes S when run, returns M's carrier of (A, S) |
action, run, lift, get, put, modify |
WriterT[M, W] |
A WriterValue wrapping M's carrier of (W.Value, A) |
writer, run_writer, lift, tell, listen, censor |
OptionalT[M] |
M's carrier of Optional[A] |
lift |
ResultT[M, E] |
M's carrier of Result[A, E] |
lift |
Reader[R], State[S] and Writer[W] are the transformers over
IdentityFamily; OptionalT and ResultT over Identity are OptionalFamily
and ResultFamily[E] themselves. Each family is a Monad of fp.algebra, so
map, pure, flat_map, map2_lazy and traverse apply to its values.
Reader and State values are deferred computations: nothing runs until run.
Transformer order matters. StateT over Result returns no state on failure;
ResultT over State can return a failed Result together with the updated
state. Neither rolls back external mutation. For ResultT[State[S], E], run
with run[State[S]], whose result is Tuple[Result[A, E], S], and lift
State's operations into the ResultT layer; for StateT[ResultFamily[E], S],
run with that StateT, whose result is Result[Tuple[A, S], E].
| Stack | Evaluation order | Final shape |
|---|---|---|
WriterT[Reader[R], W] |
run_writer, then Reader run |
(log, value) |
ReaderT[Writer[W], R] |
Reader run, then run_writer |
(log, value) |
WriterT[State[S], W] |
run_writer, then State run |
((log, value), state) |
StateT[Writer[W], S] |
State run, then run_writer |
(log, (value, state)) |
OptionalT[ResultT[M, E]] carries M[Result[Optional[A], E]], and
ResultT[OptionalT[M], E] carries M[Optional[Result[A, E]]]. Either an
absence or a stored error skips later callbacks and lazy right operands,
without converting one failure kind into the other. Native exceptions from any
stage propagate with their exact types instead of becoming Result data.
Traversal into a layer delegates to the base's traversal loop with the layer's accumulation rule, so the count of pulls and callback calls is the same over eager, deferred and third-party bases. A deferred computation can be copied or replayed only when its stored inputs and callbacks support it; copying an owner does not make a consuming callback reusable.
Summary¶
| Name | Kind | Summary |
|---|---|---|
action |
function | A computation of family I with payload T from a native endpoint callback. |
ask |
function | A Reader computation whose payload is a copy of the environment. |
censor |
function | Replace the final log with f(log). |
get |
function | A State computation whose payload is a copy of the state, which is kept. |
lift |
function | Embed a base carrier as a value of the layer I over it. |
listen |
function | Pair the payload with a copy of the log written so far; the log is kept. |
local |
function | A Reader computation that runs value with the environment f computes from the current one. |
modify |
function | A State computation that replaces the state with f(state); its payload is None. |
put |
function | A State computation that replaces the state; the previous state is destroyed. |
run |
function | Run a Reader computation of family I with a borrowed environment. |
run_writer |
function | Remove the Writer layer and return the base carrier of (log, value); a deferred base is returned unrun. |
tell |
function | A Writer value that records log, with payload None. |
writer |
function | Make a Writer value from a base carrier whose payload is exactly (log, value). |
ReaderT |
struct | Reader over the base Monad M: a computation borrows an environment R when run and returns an M carrier. |
StateT |
struct | State over the base Monad M: a computation consumes a state S when run and returns an M carrier of (value, state). |
WriterT |
struct | Writer over the base Monad M: a value is M's carrier of (log, payload), and the monoid W accumulates the log. |
WriterValue |
struct | A Writer value of family I: the base carrier C of (log, T). |
ReaderAction |
trait | A computation that reads a borrowed environment when run: a value of a ReaderT family. |
StateAction |
trait | A computation that consumes a state when run and returns the base carrier of (Value, State): a value of a StateT family. |
OptionalT |
alias | Optional over the base Monad M: a value is M's carrier of Optional[A]; over Identity, OptionalFamily. |
Reader |
alias | Reader over the bare value: a computation borrows an R and returns its payload. |
ResultT |
alias | Result over the base Monad M: a value is M's carrier of Result[A, E]; over Identity, ResultFamily[E]. |
State |
alias | State over the bare value: a computation consumes an S and returns (value, state). |
Writer |
alias | Writer over the bare value: a value is (log, payload). |
Functions¶
action¶
Source: fp/effects/operations.mojo
def action[F, //, I: _Acting, T](var f: F) -> I.Endpoint[T, F]
A computation of family I with payload T from a native endpoint callback.
For Reader, f borrows the environment (a BorrowCallable or
BorrowOnceCallable) and returns the base's carrier of T; for State, f
is a unary callback that consumes the state and returns the base's carrier
of (T, state).
Parameters
F(Movable & Deinitable, inferred): The callback's type.I: The Reader or State family.T(Movable & Deinitable): The payload type.
Arguments
f(var F): The callback, consumed.
Returns
I.Endpoint[T, F]: The computation; nothing runs now.
ask¶
Source: fp/effects/reader.mojo
def ask[I: _ReaderFamily]() -> _ReaderAsk[I.Base, downcast[I.Environment, Copyable & Deinitable]] where conforms_to(I.Environment, Copyable)
A Reader computation whose payload is a copy of the environment.
Parameters
I: The Reader family; its environment must beCopyable.
Returns
The computation.
censor¶
Source: fp/effects/writer.mojo
def censor[F: UnaryContract & Movable & Deinitable, V, //, I: _WriterFamily](
var f: F,
var value: V,
) raises I.Base.MapError[_Value[V].Storage, _Censor[F, _Value[V].Value]] -> WriterValue[ I, _Value[V].Value, I.Base.Mapped[_Value[V].Storage, _Censor[F, _Value[V].Value]]]
Replace the final log with f(log).
Other overloads take a native function or closure directly.
Parameters
F(UnaryContract & Movable & Deinitable, inferred): The callback's type: a libraryUnaryvalue from log to log.V(Movable & Deinitable, inferred): The Writer value's type.I: The Writer family.
Arguments
f(var F): The callback, consumed.value(var V): The Writer value, consumed.
Returns
WriterValue[...]: The Writer value with the new log.
Raises
I.Base.MapError[...]: The base's map error, which includes the callback's.
2 more overloads
Replace the final log with f(log), for a native function or closure.
def censor[A, R, V, //, I: _WriterFamily, F: _Unary[A, R]](
var f: F,
var value: V,
) raises I.Base.MapError[_Value[V].Storage, _Censor[NativeUnary[A, R, Never, F, False], _Value[V].Value]] -> WriterValue[ I, _Value[V].Value, I.Base.Mapped[_Value[V].Storage, _Censor[NativeUnary[A, R, Never, F, False], _Value[V].Value]]] where A == I.Log.Value and R == I.Log.Value
Raising form of the native censor; its error type is kept.
def censor[A, R, E, V, //, I: _WriterFamily, F: _RaisingUnary[A, R, E]](
var f: F,
var value: V,
) raises I.Base.MapError[_Value[V].Storage, _Censor[NativeUnary[A, R, E, F, True], _Value[V].Value]] -> WriterValue[ I, _Value[V].Value, I.Base.Mapped[_Value[V].Storage, _Censor[NativeUnary[A, R, E, F, True], _Value[V].Value]]] where A == I.Log.Value and R == I.Log.Value
get¶
Source: fp/effects/state.mojo
def get[I: _StateFamily]() -> _StateGet[I.Base, downcast[I.StateType, Copyable & Deinitable]] where conforms_to(I.StateType, Copyable)
A State computation whose payload is a copy of the state, which is kept.
Parameters
I: The State family; its state must beCopyable.
Returns
The computation.
lift¶
Source: fp/effects/operations.mojo
def lift[V, //, I: _Lifting](var value: V) raises I.LiftError[V] -> I.Lifted[V]
Embed a base carrier as a value of the layer I over it.
Parameters
V(Movable & Deinitable, inferred): The base carrier's type.I: The layer, such asReaderT[M, R]orOptionalT[M].
Arguments
value(var V): The base carrier, consumed.
Returns
I.Lifted[V]: The layer's value.
Raises
I.LiftError[V]: The layer's lift error; Writer's comes from its monoid's empty.
listen¶
Source: fp/effects/writer.mojo
def listen[V, //, I: _WriterFamily](
var value: V,
) raises I.Base.MapError[_Value[V].Storage, _Listen[I.Log, _Value[V].Value]] -> WriterValue[ I, Tuple[_Value[V].Value, I.Log.Value], I.Base.Mapped[_Value[V].Storage, _Listen[I.Log, _Value[V].Value]]]
Pair the payload with a copy of the log written so far; the log is kept.
The log must be Copyable.
Parameters
V(Movable & Deinitable, inferred): The Writer value's type.I: The Writer family.
Arguments
value(var V): The Writer value, consumed.
Returns
WriterValue[...]: The Writer value of (payload, log).
Raises
I.Base.MapError[...]: The base's map error.
local¶
Source: fp/effects/reader.mojo
def local[
S: ReaderAction, F: BorrowCallContract & Movable & Deinitable, //, I:
_ReaderFamily,
](
var f: F,
var value: S,
) -> _ReaderLocal[I.Base, downcast[I.Environment, Movable & Deinitable], S, F]
A Reader computation that runs value with the environment f computes from the current one.
The changed environment lives only for that run, so the base must not keep
it; local over such a base is a compile error. Other overloads take a
native function or closure that reads the current environment.
Parameters
S(ReaderAction, inferred): The computation's type.F(BorrowCallContract & Movable & Deinitable, inferred): The callback's type: aBorrowCallabletaking the environment.I: The Reader family.
Arguments
f(var F): The callback, consumed.value(var S): The computation, consumed.
Returns
The computation; nothing runs now.
2 more overloads
Run value with the environment a native function or closure computes from the current one, which it borrows.
def local[
S: ReaderAction, P: AnyType, R, //, I: _ReaderFamily, F: _Borrowing[P, R],
](
var f: F,
var value: S,
) -> _ReaderLocal[I.Base, downcast[I.Environment, Movable & Deinitable], S, _NativeBorrow[P, R, Never, F, False]] where P == I.Environment and R == I.Environment
Raising form of the native local; its error type is kept.
def local[
S: ReaderAction, P: AnyType, R, E, //, I: _ReaderFamily, F:
_RaisingBorrowing[P, R, E],
](
var f: F,
var value: S,
) -> _ReaderLocal[I.Base, downcast[I.Environment, Movable & Deinitable], S, _NativeBorrow[P, R, E, F, True]] where P == I.Environment and R == I.Environment
modify¶
Source: fp/effects/state.mojo
def modify[F: UnaryContract & Movable & Deinitable, //, I: _StateFamily](
var f: F,
) -> _StateModify[I.Base, I.StateType, F]
A State computation that replaces the state with f(state); its payload is None.
Other overloads take a native function or closure directly.
Parameters
F(UnaryContract & Movable & Deinitable, inferred): The callback's type: a libraryUnaryvalue from state to state.I: The State family.
Arguments
f(var F): The callback, consumed.
Returns
The computation.
2 more overloads
Replace the state with f(state), for a native function or closure.
def modify[A, R, //, I: _StateFamily, F: _Unary[A, R]](
var f: F,
) -> _StateModify[I.Base, I.StateType, NativeUnary[A, R, Never, F, False]] where A == I.StateType and R == I.StateType
Raising form of the native modify; its error type is kept.
def modify[A, R, E, //, I: _StateFamily, F: _RaisingUnary[A, R, E]](
var f: F,
) -> _StateModify[I.Base, I.StateType, NativeUnary[A, R, E, F, True]] where A == I.StateType and R == I.StateType
put¶
Source: fp/effects/state.mojo
def put[I: _StateFamily](
var state: I.StateType,
) -> _StateModify[I.Base, I.StateType, _Replace[I.StateType]]
A State computation that replaces the state; the previous state is destroyed.
Parameters
I: The State family.
Arguments
state(var I.StateType): The new state, consumed.
Returns
The computation.
run¶
Source: fp/effects/operations.mojo
def run[V, o: ImmOrigin, //, I: _ReaderFamily](
var action: V,
ref[o] env: I.Environment,
) raises _Reader[V].Error[o] -> _Reader[V].Out[o]
Run a Reader computation of family I with a borrowed environment.
Another overload runs a State computation with an initial state.
Parameters
V(Movable & Deinitable, inferred): The computation's type.o(ImmOrigin, inferred): The environment's origin.I: The Reader family.
Arguments
action(var V): The computation, consumed.env(ref[o] I.Environment): The environment, borrowed for the run.
Returns
The base carrier of the payload.
Raises
The common error of the stages the run executes.
1 more overload
Run a State computation of family `I`, consuming the initial state.
def run[V, //, I: _StateFamily](
var action: V,
var state: I.StateType,
) raises _State[V].Error -> _State[V].Out
run_writer¶
Source: fp/effects/writer.mojo
def run_writer[V, //, I: _WriterFamily](var value: V) -> _Value[V].Storage
Remove the Writer layer and return the base carrier of (log, value); a deferred base is returned unrun.
Parameters
V(Movable & Deinitable, inferred): The Writer value's type.I: The Writer family.
Arguments
value(var V): The Writer value, consumed.
Returns
The base carrier.
tell¶
Source: fp/effects/writer.mojo
def tell[I: _WriterFamily](
var log: I.Log.Value,
) -> WriterValue[I, NoneType, I.Base.Pure[Tuple[I.Log.Value, NoneType]]]
A Writer value that records log, with payload None.
Parameters
I: The Writer family.
Arguments
log(var I.Log.Value): The log to record, consumed.
Returns
WriterValue[I, NoneType, I.Base.Pure[Tuple[I.Log.Value, NoneType]]]: The Writer value.
writer¶
Source: fp/effects/writer.mojo
def writer[C, //, I: _WriterFamily, T](var carrier: C) -> WriterValue[I, T, C]
Make a Writer value from a base carrier whose payload is exactly (log, value).
Parameters
C(Movable & Deinitable, inferred): The base carrier's type.I: The Writer family.T(Movable & Deinitable): The payload type.
Arguments
carrier(var C): The base carrier, consumed.
Returns
WriterValue[I, T, C]: The Writer value.
Structs¶
ReaderT¶
Source: fp/effects/reader.mojo
struct ReaderT[M: Monad, R: AnyType](_ReaderFamily, _Lifting)
Reader over the base Monad M: a computation borrows an environment R when run and returns an M carrier.
Every operation returns a concrete computation that stores its inputs; a
composed computation's type is the tree of its operations, and nothing runs
until run. Constructing a computation does not raise; its run raises the
exact common error of the stages it executes. On Mojo 1.1 that error cannot
propagate from a function declared with a plain raises; handle it with
try/except, where it keeps its exact type. The base is used only through
its Monad methods, so any Monad, including another Reader or State, can be
the base. Traversal delegates to the base's collect, whose callback runs
each produced computation with the borrowed environment.
Parameters
M(Monad): The base Monad.R(AnyType): The environment's type.
Implements
Applicative, Functor, Monad, _Acting, _Lifting, _ReaderFamily
Aliases
BaseEnvironmentElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorLiftedEndpointLiftErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
ReaderT.endpoint¶
def endpoint[T, F](var f: F) -> Endpoint[T, F]
A Reader computation from a callback that borrows the environment; action[I, T](f) calls this.
Parameters
T(Movable & Deinitable): The payload type.F(Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.
Returns
Endpoint[T, F]: The computation.
ReaderT.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) -> Bound[V, F]
A Reader computation that runs value, then the computation f returns, in the same environment.
Parameters
V(Movable & Deinitable): The computation's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a computation of this family.
Arguments
f(var F): The callback, consumed.value(var V): The computation, consumed.
Returns
Bound[V, F]: The bound computation; nothing runs now.
ReaderT.lift¶
def lift[V](var value: V) -> Lifted[V]
A Reader computation that ignores the environment and returns a base carrier.
Parameters
V(Movable & Deinitable): The base carrier's type.
Arguments
value(var V): The base carrier, consumed.
Returns
Lifted[V]: The computation.
ReaderT.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) -> Mapped[V, F]
A Reader computation that maps the payload of value with f when run.
Parameters
V(Movable & Deinitable): The computation's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The computation, consumed.
Returns
Mapped[V, F]: The mapping computation; nothing runs now.
ReaderT.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, G: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: G,
) -> Combined[V, F, G]
A Reader computation that runs both operands in the same environment and combines their payloads.
Parameters
V(Movable & Deinitable): The left computation's type.F(BinaryContract & Movable & Deinitable): The combiner's type.G(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a computation of this family.
Arguments
f(var F): The combiner, consumed.left(var V): The left computation, consumed.right(var G): The thunk producing the right computation, consumed.
Returns
Combined[V, F, G]: The combining computation; nothing runs now.
ReaderT.pure¶
def pure[A](var value: A) -> Pure[A]
A Reader computation that ignores the environment and returns value in the base.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The computation.
StateT¶
Source: fp/effects/state.mojo
struct StateT[M: Monad, S](_StateFamily, _Lifting)
State over the base Monad M: a computation consumes a state S when run and returns an M carrier of (value, state).
Computations are built as for ReaderT and run with run. Traversal is one
loop: it checks that the base carrier still has a live branch, pulls one
item, calls the producer once, and binds the prepared computation across
the live branches, each on its own state. A failed, absent or empty carrier
stops producer calls and source pulls. The base carrier's type must stay
the same across steps, as it does for Identity, Optional, Result and List;
a deferred base is a compile error there.
Parameters
M(Monad): The base Monad.S(Movable & Deinitable): The state's type.
Implements
Applicative, Functor, Monad, _Acting, _Lifting, _StateFamily
Aliases
BaseStateTypeElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorLiftedEndpointLiftErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
StateT.endpoint¶
def endpoint[T, F](var f: F) -> Endpoint[T, F]
A State computation from a callback that consumes the state; action[I, T](f) calls this.
Parameters
T(Movable & Deinitable): The payload type.F(Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.
Returns
Endpoint[T, F]: The computation.
StateT.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) -> Bound[V, F]
A State computation that runs value, then the computation f returns on the updated state.
Parameters
V(Movable & Deinitable): The computation's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a computation of this family.
Arguments
f(var F): The callback, consumed.value(var V): The computation, consumed.
Returns
Bound[V, F]: The bound computation; nothing runs now.
StateT.lift¶
def lift[V](var value: V) -> Lifted[V]
A State computation that returns a base carrier's payload with the state unchanged.
Parameters
V(Movable & Deinitable): The base carrier's type.
Arguments
value(var V): The base carrier, consumed.
Returns
Lifted[V]: The computation.
StateT.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) -> Mapped[V, F]
A State computation that maps the payload of value with f when run; the state passes through.
Parameters
V(Movable & Deinitable): The computation's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The computation, consumed.
Returns
Mapped[V, F]: The mapping computation; nothing runs now.
StateT.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, G: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: G,
) -> Combined[V, F, G]
A State computation that runs the left operand, then the right one on the state the left produced, and combines their payloads.
Parameters
V(Movable & Deinitable): The left computation's type.F(BinaryContract & Movable & Deinitable): The combiner's type.G(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a computation of this family.
Arguments
f(var F): The combiner, consumed.left(var V): The left computation, consumed.right(var G): The thunk producing the right computation, consumed.
Returns
Combined[V, F, G]: The combining computation; nothing runs now.
StateT.pure¶
def pure[A](var value: A) -> Pure[A]
A State computation that returns value and the state unchanged.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The computation.
WriterT¶
Source: fp/effects/writer.mojo
struct WriterT[M: Monad, W: Monoid](_WriterFamily, _Lifting)
Writer over the base Monad M: a value is M's carrier of (log, payload), and the monoid W accumulates the log.
Operations use the base's own map, flat_map and map2_lazy, so over a
deferred base a Writer value stays deferred; logs combine in execution
order. pure requires a monoid whose empty does not raise.
Parameters
M(Monad): The base Monad.W(Monoid): The log's monoid.
Implements
Applicative, Functor, Monad, _Lifting, _WriterFamily
Aliases
BaseLogElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorLiftedLiftErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
WriterT.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises BindError[V, F] -> Bound[V, F]
Continue with the Writer value f returns, appending its log to the log so far.
Parameters
V(Movable & Deinitable): The Writer value's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a Writer value of this family.
Arguments
f(var F): The callback, consumed.value(var V): The Writer value, consumed.
Returns
Bound[V, F]: The bound Writer value.
Raises
BindError[V, F]: The base's bind error, which includes the callback's and the monoid's.
WriterT.lift¶
def lift[V](var value: V) raises LiftError[V] -> Lifted[V]
A Writer value with a base carrier's payload and the empty log.
Parameters
V(Movable & Deinitable): The base carrier's type.
Arguments
value(var V): The base carrier, consumed.
Returns
Lifted[V]: The Writer value.
Raises
LiftError[V]: The monoid's empty error, through the base's map.
WriterT.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises MapError[V, F] -> Mapped[V, F]
Map the payload with f, keeping the log, through the base's map.
Parameters
V(Movable & Deinitable): The Writer value's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The Writer value, consumed.
Returns
Mapped[V, F]: The mapped Writer value.
Raises
MapError[V, F]: The base's map error, which includes the callback's.
WriterT.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, G: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: G,
) raises CombineError[V, F, G] -> Combined[V, F, G]
Combine two Writer values: the logs in order, the payloads with f.
Parameters
V(Movable & Deinitable): The left Writer value's type.F(BinaryContract & Movable & Deinitable): The combiner's type.G(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a Writer value.
Arguments
f(var F): The combiner, consumed.left(var V): The left Writer value, consumed.right(var G): The thunk producing the right Writer value, consumed.
Returns
Combined[V, F, G]: The combined Writer value.
Raises
CombineError[V, F, G]: The base's combination error, which includes the combiner's, the thunk's and the monoid's.
WriterT.pure¶
def pure[A](var value: A) -> Pure[A]
A Writer value with the payload and the empty log.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The Writer value.
WriterValue¶
Source: fp/effects/writer.mojo
struct WriterValue[I: _WriterFamily, T, C](
_WriterType,
Copyable where conforms_to(C, Copyable),
)
A Writer value of family I: the base carrier C of (log, T).
Parameters
I: The Writer family.T(Movable & Deinitable): The payload type.C(Movable & Deinitable): The base carrier's type.
Implements
Copyable, _Computation, _WriterType
Fields
value(C): The base carrier of(log, payload).
Aliases
FamilyValueStorage
WriterValue.into_base¶
def into_base(deinit self) -> C
Consume the Writer value and return its base carrier, unrun.
Returns
C: The base carrier of (log, payload).
Traits¶
ReaderAction¶
Source: fp/effects/protocols.mojo
trait ReaderAction(_Computation)
A computation that reads a borrowed environment when run: a value of a ReaderT family.
Family is the ReaderT instance the computation belongs to and Value
its payload. A result and error take the environment's origin o, so a
base that keeps the environment, such as a Reader over another Reader,
keeps its exact origin.
Implements
_Computation
Associated aliases
Env: The environment's type.Out: The base carrier a run with an environment of originoreturns.Error: The error such a run raises;Neverby default.
ReaderAction.run¶
def run[o: ImmOrigin](deinit self, ref[o] env: Env) raises Error[o] -> Out[o]
Run the computation, consuming it, with a borrowed environment.
Parameters
o(ImmOrigin): The environment's origin.
Arguments
env(ref[o] Env): The environment, borrowed for the run.
Returns
Out[o]: The base carrier of the payload.
Raises
Error[o]: The common error of the stages the run executes.
StateAction¶
Source: fp/effects/protocols.mojo
trait StateAction(_Computation)
A computation that consumes a state when run and returns the base carrier of (Value, State): a value of a StateT family.
Implements
_Computation
Associated aliases
State: The state's type.Out: The base carrier a run returns.Error: The error a run raises;Neverby default.
StateAction.run¶
def run(deinit self, var state: State) raises Error -> Out
Run the computation, consuming it and the state.
Arguments
state(var State): The initial state, consumed.
Returns
Out: The base carrier of the payload and the final state.
Raises
Error: The common error of the stages the run executes.
Aliases¶
OptionalT¶
Source: fp/effects/layers.mojo
comptime OptionalT[M: Monad]: Monad & _Lifting = OptionalFamily if M == IdentityFamily else _OptionalT[M]
Optional over the base Monad M: a value is M's carrier of Optional[A]; over Identity, OptionalFamily.
A value is the base carrier itself, run with the base's run. An absent value
skips later callbacks and right operands and keeps the base's earlier effects.
Parameters
M(Monad): The base Monad.
Reader¶
Source: fp/effects/reader.mojo
comptime Reader[R: AnyType] = ReaderT[IdentityFamily, R]
Reader over the bare value: a computation borrows an R and returns its payload.
Parameters
R(AnyType): The environment's type.
ResultT¶
Source: fp/effects/layers.mojo
comptime ResultT[M: Monad, E]: Monad & _Lifting = ResultFamily[E] if M == IdentityFamily else _ResultT[M, E]
Result over the base Monad M: a value is M's carrier of Result[A, E]; over Identity, ResultFamily[E].
A stored error skips later callbacks and right operands and keeps the base's earlier effects; it is never converted into an absence, nor a native error.
Parameters
M(Monad): The base Monad.E(Movable & Deinitable): The stored error type.
State¶
Source: fp/effects/state.mojo
comptime State[S] = StateT[IdentityFamily, S]
State over the bare value: a computation consumes an S and returns (value, state).
Parameters
S(Movable & Deinitable): The state's type.
Writer¶
Source: fp/effects/writer.mojo
comptime Writer[W: Monoid] = WriterT[IdentityFamily, W]
Writer over the bare value: a value is (log, payload).
Parameters
W(Monoid): The log's monoid.
Choose whether a failure keeps its state¶
"""Transformer order decides whether a stored failure returns the updated state."""
from fp.algebra import pure, flat_map
from fp.effects import State, StateT, ResultT, run, lift, put
from fp.algebra import ResultFamily
from fp.data import Result, Err
from std.testing import assert_equal
comptime DomainResult=Result[Int,String]
comptime Keep=ResultT[State[Int],String]
comptime Discard=StateT[ResultFamily[String],Int]
def failure()->DomainResult:
return Err(String("rejected"))
# Each adapter places the same domain failure at its stack's base boundary.
def fail_keep(var unused:NoneType)->type_of(pure[State[Int]](failure())):
return pure[State[Int]](failure())
def fail_discard(var unused:NoneType)->type_of(lift[Discard](failure())):
return lift[Discard](failure())
def main() raises:
var kept=run[State[Int]](flat_map[Keep](fail_keep,lift[Keep](put[State[Int]](15))),10)
comptime assert type_of(kept)==Tuple[DomainResult,Int]
ref result=kept[0]
var state=kept[1]
assert_equal(result.is_err(),True)
assert_equal(state,15)
print("ResultT[State]: failed, returned state =",state)
var discarded=run[Discard](flat_map[Discard](fail_discard,put[Discard](15)),10)
comptime assert type_of(discarded)==Result[Tuple[Int,Int],String]
assert_equal(discarded.is_err(),True)
print("StateT[Result]: failed, no state payload")
Run from the repository root pixi run mojo run -I src docs/examples/state_result.mojo
Output
ResultT[State]: failed, returned state = 15
StateT[Result]: failed, no state payload
Both stacks start from state 10, set it to 15 with put, then fail with
Err("rejected"). With ResultT[State[Int], String], run returns the
failed Result together with the state 15. With
StateT[ResultFamily[String], Int], run returns only the Err, and the state
is lost with it.