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
A note on the HasSink super class.
HasSink offers one
yield method with the same signature
as
tell. Many people's intuition, however, wouldn't connect the
two:
yielding tosses the value down some black-box chute, while
telling grows and accumulation via the monoid. The connection
is since the
chute is opaque, the tosser cannot rule out
there being such an accumulation at the chutes other end.
Formally, we reach the same conclusion.
HasSink has no laws,
indicating the user can make no assumptions beyond the signature of
yield.
HasWriter, with
tell defined as
yield, is thus always compatable regardless of whatever
additional methods it provides and laws by which it abides.