Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Control.Writer

The canonical Writer(w) effect: accumulate output on the side.

tell(m) appends m to a log the producer never sees; run_writer returns the computation’s result paired with the whole log in emission order. The handler threads the growing log as a parameter (tail-resumptive, so it fuses), so nothing shared or mutable is involved. eval_writer keeps only the result, exec_writer only the log, and listen/censor observe or rewrite an inner computation’s log while staying inside the effect. Opt-in: not in Base.

Effects

Writer

effect Writer(w)
  tell(w) : Unit

Append one item of type w to the accumulated log.

Functions and Values

run_writer

run_writer : forall e0 a b. (() -> a ! {Control.Writer.Writer(b), e0}) -> (a, List(b)) ! {e0}

Run action, collecting every tell into a log, and return the computation’s result paired with that log in emission order.

run_writer(\() -> tells(["started", "finished"]))
((), [started, finished])

eval_writer

eval_writer : forall e0 a b. (() -> a ! {Control.Writer.Writer(b), e0}) -> a ! {e0}

Run action and keep only its result, discarding the log.

exec_writer

exec_writer : forall e0 a b. (() -> a ! {Control.Writer.Writer(b), e0}) -> List(b) ! {e0}

Run action and keep only the log, discarding the result.

listen

listen : forall e0 a b. (() -> a ! {Control.Writer.Writer(b), Control.Writer.Writer(b), e0}) -> (a, List(b)) ! {Control.Writer.Writer(b), e0}

Run action, re-emit its log unchanged, and return the result paired with that log, so an outer writer both observes and keeps the inner output.

censor

censor : forall e0 a b. ((List(a)) -> List(a), () -> b ! {Control.Writer.Writer(a), Control.Writer.Writer(a), e0}) -> b ! {Control.Writer.Writer(a), e0}

Run action, rewrite its whole log with f, and re-emit the rewritten log, returning the result. The rewrite sees the log in emission order.

exec_writer(\() -> censor(reverse, \() -> tells(["a", "b"])))
[b, a]

tells

tells : forall a. (List(a)) -> Unit ! {Control.Writer.Writer(a)}

Emit every item of log in order.