Copyright | (c) 2021 Xy Ren |
---|---|

License | BSD3 |

Maintainer | xy.r@outlook.com |

Stability | experimental |

Portability | non-portable (GHC only) |

Safe Haskell | Trustworthy |

Language | Haskell2010 |

## Synopsis

- data Writer w :: Effect where
- tell :: Writer w :> es => w -> Eff es ()
- listen :: Writer w :> es => Eff es a -> Eff es (a, w)
- listens :: Writer w :> es => (w -> x) -> Eff es a -> Eff es (a, x)
- runWriter :: forall w es a. Monoid w => Eff (Writer w ': es) a -> Eff es (a, w)
- runWriterBatch :: forall w es a. Monoid w => Eff (Writer w ': es) a -> Eff es (a, w)

# Effect

data Writer w :: Effect where Source #

An effect capable of accumulating outputs. This roughly corresponds to the `MonadWriter`

typeclass and `WriterT`

monad transformer in the `mtl`

approach.

However, note that this does not have a `pass`

operation as we are not sure what its semantics should be. In fact,
the `pass`

semantics in `mtl`

is also unclear and will change when handlers are put in different orders. To avoid
any confusion we decided it is best that we don't include it because no one seems to be relying on it anyway.

# Operations

listens :: Writer w :> es => (w -> x) -> Eff es a -> Eff es (a, x) Source #

Apply a function to the accumulated output of `listen`

.

# Interpretations

runWriterBatch :: forall w es a. Monoid w => Eff (Writer w ': es) a -> Eff es (a, w) Source #

Run a monoidal `Writer`

effect, but appends the listened output to the parent value only when the listen operation
finishes. This means that when you run two `listen`

s on two threads, the values `tell`

ed inside will not be appended
to the parent value in real time, but only after the thread finishes `listen`

ing. For example, this code

`concurrently_`

(`listen`

`$`

`tell`

"1"`>>`

`tell`

"2"`>>`

`tell`

"3") (`listen`

`$`

`tell`

"4"`>>`

`tell`

"5"`>>`

`tell`

"6")

will produce either `"123456"`

or `"456123"`

with `runWriterBatch`

, but may produce these digits in any order with
`runWriter`

.

This version of interpreter can be slightly faster than `runWriter`

in `listen`

-intense code. It is subject to all
caveats of `runWriter`

.