View Source Funx.Monad.Writer (funx v0.1.3)
The Funx.Monad.Writer
module defines the Writer monad, which threads a log alongside a computed result.
Logs are accumulated using a Monoid
implementation, injected lazily at runtime. This makes the Writer monad flexible and monoid-polymorphic—supporting lists, strings, or any user-defined monoid.
Core functions
pure/1
– Wraps a result with an empty log.writer/1
– Wraps a result and an explicit log.tell/1
– Emits a log with no result.listen/1
– Returns both result and log as a pair.censor/2
– Applies a function to transform the final log.pass/1
– Uses a log-transforming function returned from within the computation.run/2
– Executes the Writer and returns a%Writer.Result{}
with result and log.eval/2
– Executes and returns only the result.exec/2
– Executes and returns only the log.
By default, the ListConcat
monoid is used unless a different monoid is passed to run
, eval
, or exec
.
This module also implements the Funx.Monad
protocol.
Summary
Types
Represents a computation that produces a result along with a log, accumulated using a monoid.
Functions
Transforms the final log by applying a function to it.
Executes the Writer and returns only the final result value.
Executes the Writer and returns only the final accumulated log.
Captures the current log and returns it alongside the result.
Applies a log-transforming function that is returned from within the computation.
Wraps a value with no log.
Executes the Writer and returns both the result and the final accumulated log.
Appends a log value using the monoid, returning :ok
as the result.
Wraps both a value and a raw log into the Writer context.
Types
Represents a computation that produces a result along with a log, accumulated using a monoid.
The internal writer
function takes an initial monoid and returns
a {value, monoid}
tuple, where the monoid contains the accumulated log.
Functions
Transforms the final log by applying a function to it.
The result remains unchanged—only the log is modified.
Example
iex> writer = Funx.Monad.Writer.writer({"ok", [:a, :b]})
iex> censored = Funx.Monad.Writer.censor(writer, fn log -> Enum.reverse(log) end)
iex> result = Funx.Monad.Writer.run(censored)
iex> result.value
"ok"
iex> result.log
[:b, :a]
Executes the Writer and returns only the final result value.
Uses ListConcat
by default.
Example
iex> writer =
...> Funx.Monad.Writer.writer({10, [:init]})
...> |> Funx.Monad.bind(fn x ->
...> Funx.Monad.Writer.tell([:logged])
...> |> Funx.Monad.bind(fn _ -> Funx.Monad.Writer.pure(x * 2) end)
...> end)
iex> Funx.Monad.Writer.eval(writer)
20
Executes the Writer and returns only the final accumulated log.
Uses ListConcat
by default.
Example
iex> writer =
...> Funx.Monad.Writer.writer({:ok, [:step1]})
...> |> Funx.Monad.bind(fn _ -> Funx.Monad.Writer.tell([:step2]) end)
iex> Funx.Monad.Writer.exec(writer)
[:step1, :step2]
Captures the current log and returns it alongside the result.
The log remains unchanged—only the result is modified to include it.
Example
iex> writer = Funx.Monad.Writer.writer({"done", [:start, :finish]})
iex> listened = Funx.Monad.Writer.listen(writer)
iex> result = Funx.Monad.Writer.run(listened)
iex> result.value
{"done", [:start, :finish]}
iex> result.log
[:start, :finish]
Applies a log-transforming function that is returned from within the computation.
This allows the result of a computation to include not only a value, but also a function that modifies the final accumulated log.
The input to pass/1
must be a Writer containing a tuple {result, f}
, where
f
is a function from log to log. This function will be applied to the final log
just before it's returned.
Example
iex> result =
...> Funx.Monad.Writer.pure({"done", fn log -> log ++ [:transformed] end})
...> |> Funx.Monad.Writer.pass()
...> |> Funx.Monad.Writer.run()
iex> result.value
"done"
iex> result.log
[:transformed]
Wraps a value with no log.
Example
iex> writer = Funx.Monad.Writer.pure(42)
iex> result = Funx.Monad.Writer.run(writer)
iex> result.value
42
iex> result.log
[]
@spec run(t(a), monoid) :: Funx.Monad.Writer.Result.t(a, log) when a: term(), log: term(), monoid: term()
Executes the Writer and returns both the result and the final accumulated log.
By default, it uses ListConcat
unless a monoid is explicitly passed.
Example
iex> writer = Funx.Monad.Writer.writer({"ok", [:a, :b]})
iex> result = Funx.Monad.Writer.run(writer)
iex> result.value
"ok"
iex> result.log
[:a, :b]
Appends a log value using the monoid, returning :ok
as the result.
Example
iex> writer = Funx.Monad.Writer.tell([:event])
iex> result = Funx.Monad.Writer.run(writer)
iex> result.value
:ok
iex> result.log
[:event]
Wraps both a value and a raw log into the Writer context.
Example
iex> writer = Funx.Monad.Writer.writer({:ok, [:step1, :step2]})
iex> result = Funx.Monad.Writer.run(writer)
iex> result.value
:ok
iex> result.log
[:step1, :step2]