Free Monad #
This file defines several canonical instances on the free monad.
Main definitions #
FreeState,FreeWriter,FreeCont: Specific effect monads
Implementation #
To execute or interpret these computations, we provide two approaches:
- Hand-written interpreters (
FreeState.run,FreeWriter.run,FreeCont.run) that directly pattern-match on the tree structure - Canonical interpreters (
FreeState.toStateM,FreeWriter.toWriterT,FreeCont.toContT) derived from the universal property vialiftM
We prove that these approaches are equivalent, demonstrating that the implementation aligns with the theory. We also provide uniqueness theorems for the canonical interpreters, which follow from the universal property.
Tags #
Free monad, state monad, writer monad, continuation monad
State Monad via FreeM #
Type constructor for state operations.
- get
{σ : Type u}
: StateF σ σ
Get the current state.
- set
{σ : Type u}
: σ → StateF σ PUnit.{u + 1}
Set the state.
Instances For
State monad via the FreeM monad.
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Convert a FreeState computation into a StateM computation. This is the canonical
interpreter derived from liftM.
Equations
- comp.toStateM = Cslib.FreeM.liftM (fun {ι : Type ?u.18} => Cslib.FreeM.FreeState.stateInterp) comp
Instances For
toStateM is the unique interpreter extending stateInterp.
Run a state computation, returning both the result and final state.
Equations
- Cslib.FreeM.FreeState.run (Cslib.FreeM.pure a) s₀ = (a, s₀)
- Cslib.FreeM.FreeState.run (Cslib.FreeM.liftBind Cslib.FreeM.StateF.get k) s₀ = Cslib.FreeM.FreeState.run (k s₀) s₀
- Cslib.FreeM.FreeState.run (Cslib.FreeM.liftBind (Cslib.FreeM.StateF.set s') k) s₀ = Cslib.FreeM.FreeState.run (k PUnit.unit) s'
Instances For
Writer Monad via FreeM #
Type constructor for writer operations. Writer has a single effect, so the definition has just one constructor.
- tell
{ω : Type u}
: ω → WriterF ω PUnit.{v + 1}
Write a value to the log.
Instances For
Writer monad implemented via the FreeM monad construction. This provides a more efficient
implementation than the traditional WriterT transformer, as it avoids buffering the log.
Equations
Instances For
Convert a FreeWriter computation into a WriterT computation. This is the canonical
interpreter derived from liftM.
Equations
- comp.toWriterT = Cslib.FreeM.liftM (fun {ι : Type ?u.8} => Cslib.FreeM.FreeWriter.writerInterp) comp
Instances For
toWriterT is the unique interpreter extending writerInterp.
Writes a log entry. This creates an effectful node in the computation tree.
Equations
Instances For
Interprets a FreeWriter computation by recursively traversing the tree, accumulating
log entries with the monoid operation, and returns the final value paired with the accumulated log.
Equations
- Cslib.FreeM.FreeWriter.run (Cslib.FreeM.pure a) = (a, 1)
- Cslib.FreeM.FreeWriter.run (Cslib.FreeM.liftBind (Cslib.FreeM.WriterF.tell w) k) = match Cslib.FreeM.FreeWriter.run (k PUnit.unit) with | (a, w') => (a, w * w')
Instances For
The canonical interpreter toWriterT derived from liftM agrees with the hand-written
recursive interpreter run for FreeWriter.
listen captures the log produced by a subcomputation incrementally. It traverses the computation,
emitting log entries as encountered, and returns the accumulated log as a result.
Equations
- One or more equations did not get rendered due to their size.
- Cslib.FreeM.FreeWriter.listen (Cslib.FreeM.pure a) = Cslib.FreeM.pure (a, 1)
Instances For
pass allows a subcomputation to modify its own log. After traversing the computation and
accumulating its log, the resulting function is applied to rewrite the accumulated log
before re-emission.
Equations
- m.pass = match m.run with | ((a, f), w) => Cslib.FreeM.liftBind (Cslib.FreeM.WriterF.tell (f w)) fun (x : PUnit.{?u.29 + 1}) => Cslib.FreeM.pure a
Instances For
Equations
- One or more equations did not get rendered due to their size.
Continuation Monad via FreeM #
Equations
- One or more equations did not get rendered due to their size.
Continuation monad via the FreeM monad.
Equations
Instances For
Equations
Interpret ContF r operations into ContT r Id.
Equations
- Cslib.FreeM.FreeCont.contInterp (Cslib.FreeM.ContF.callCC g) x✝ = pure (g fun (a : α) => (x✝ a).run)
Instances For
Convert a FreeCont computation into a ContT computation. This is the canonical
interpreter derived from liftM.
Equations
- comp.toContT = Cslib.FreeM.liftM (fun {ι : Type ?u.7} => Cslib.FreeM.FreeCont.contInterp) comp
Instances For
toContT is the unique interpreter extending contInterp.
Run a continuation computation with the given continuation.
Equations
- Cslib.FreeM.FreeCont.run (Cslib.FreeM.pure a) x✝ = x✝ a
- Cslib.FreeM.FreeCont.run (Cslib.FreeM.liftBind (Cslib.FreeM.ContF.callCC g) cont) x✝ = g fun (a : ι) => Cslib.FreeM.FreeCont.run (cont a) x✝
Instances For
Call with current continuation for the Free continuation monad.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Cslib.FreeM.FreeCont.instMonadCont = { callCC := fun {α β : Type ?u.10} => Cslib.FreeM.FreeCont.callCC }
run of a callCC node simplifies to running the handler with the current continuation.