Safe Haskell | None |
---|---|
Language | Haskell2010 |
Defines a capability type class for writer effects. A writer program can
output values with tell
. The values output by two consecutive
sub-computation are combined using a monoid's mappend
.
The interface of HasWriter
follows that of
MonadWriter
. However, this module does not
include a strategy to provide a HasWriter
capability from a MonadWriter
instance. It is generally a bad idea to use monads such as
WriterT
, as they tend to leak space, as
described in this
<https://blog.infinitenegativeutility.com/2016/7/writer-monads-and-space-leaks
blog post> by Getty Ritter.
Instead, you should use the WriterLog
strategy that implements the writer
monad on a state monad. There is no downside, as using HasWriter
instead of
HasState
directly ensures your code adheres to the writer monad interface
and does not misuse the underlying state monad.
Synopsis
- class (Monoid w, Monad m) => HasWriter (tag :: k) (w :: *) (m :: * -> *) | tag m -> w where
- writer :: forall tag w m a. HasWriter tag w m => (a, w) -> m a
- tell :: forall tag w m. HasWriter tag w m => w -> m ()
- listen :: forall tag w m a. HasWriter tag w m => m a -> m (a, w)
- pass :: forall tag w m a. HasWriter tag w m => m (a, w -> w) -> m a
- newtype WriterLog m a = WriterLog (m a)
- module Capability.Accessors
Interface
class (Monoid w, Monad m) => HasWriter (tag :: k) (w :: *) (m :: * -> *) | tag m -> w where Source #
Writer capability
An instance should fulfill the following laws. At this point these laws are not definitive, see https://github.com/haskell/mtl/issues/5.
listen @t (pure a) = pure (a, mempty)
listen @t (tell @t w) = tell @t w >> pure (w, w)
listen @t (m >>= k) = listen @t m >>= \(a, w1) -> listen @t (k a) >>= \(b, w2) -> pure (b, w1 `mappend` w2)
pass @t (tell @t w >> pure (a, f)) = tell @t (f w) >> pure a
writer @t (a, w) = tell @t w >> pure a
writer_ :: Proxy# tag -> (a, w) -> m a Source #
For technical reasons, this method needs an extra proxy argument.
You only need it if you are defining new instances of HasReader
.
Otherwise, you will want to use writer
.
See writer
for more documentation.
tell_ :: Proxy# tag -> w -> m () Source #
For technical reasons, this method needs an extra proxy argument.
You only need it if you are defining new instances of HasReader
.
Otherwise, you will want to use tell
.
See tell
for more documentation.
Instances
(Monoid w, HasState tag w m) => HasWriter (tag :: k) w (WriterLog m) Source # | |
(forall x. Coercible (m x) (t2 (t1 m) x), Monad m, HasWriter tag w (t2 (t1 m))) => HasWriter (tag :: k) w ((t2 :.: t1) m) Source # | Compose two accessors. |
(HasWriter tag w m, MonadTransUnlift t, Monad (t m)) => HasWriter (tag :: Type) w (Lift (t m)) Source # | Lift one layer in a monad transformer stack. Note, that if the deriving (HasWriter tag w) via WriterLog (Lift (SomeTrans (MonadState SomeStateMonad))) over deriving (HasWriter tag w) via Lift (SomeTrans (WriterLog (MonadState SomeStateMonad))) |
writer :: forall tag w m a. HasWriter tag w m => (a, w) -> m a Source #
writer @tag (a, w)
lifts a pure writer action (a, w)
to a monadic action in an arbitrary
monad m
with capability HasWriter
.
Appends w
to the output of the writer capability tag
and returns the value a
.
tell :: forall tag w m. HasWriter tag w m => w -> m () Source #
tell @tag w
appends w
to the output of the writer capability tag
.
listen :: forall tag w m a. HasWriter tag w m => m a -> m (a, w) Source #
listen @tag m
executes the action m
and returns the output of m
in the writer capability tag
along with result of m
.
Appends the output of m
to the output of the writer capability tag
.
pass :: forall tag w m a. HasWriter tag w m => m (a, w -> w) -> m a Source #
pass @tag m
executes the action m
. Assuming m
returns (a, f)
and appends
w
to the output of the writer capability tag
.
pass @tag m
instead appends w' = f w
to the output and returns a
.
Strategies
newtype WriterLog m a Source #
WriterLog (m a) |
Instances
(Monoid w, HasState tag w m) => HasWriter (tag :: k) w (WriterLog m) Source # | |
Monad m => Monad (WriterLog m) Source # | |
Functor m => Functor (WriterLog m) Source # | |
Applicative m => Applicative (WriterLog m) Source # | |
Defined in Capability.Writer | |
MonadIO m => MonadIO (WriterLog m) Source # | |
Defined in Capability.Writer | |
PrimMonad m => PrimMonad (WriterLog m) Source # | |
type PrimState (WriterLog m) Source # | |
Defined in Capability.Writer |
Modifiers
module Capability.Accessors