haskell - What is the point of pass and listen in Writer monad? -
this question has answer here:
- how `pass` , `listen` work in writert? 4 answers
i have been learning monads in book learnyouahaskell. after reading writer monad, decided check documentation of control.monad.writer.class.
there saw implemented listen
, pass
functions not able understand used for. give me example can understand how use listen
, pass
?
here code control.monad.trans.writer.strict
defined listen
, pass
:
listen :: (monoid w, monad m) => writert w m -> writert w m (a, w) listen m = writert $ (a, w) <- runwritert m return ((a, w), w) pass :: (monoid w, monad m) => writert w m (a, w -> w) -> writert w m pass m = writert $ ((a, f), w) <- runwritert m return (a, f w)
writert
monad transformer provides writer
functionality other monads, simple writer
type defined type writer w = writert w identity
, in identity
monad bind function (<-
, >>=
) variable binding, if break down monadic part of code above:
listen :: (monoid w) => writer w -> writer w (a, w) listen m = writer $ let (a, w) = runwriter m in ((a, w), w) pass :: (monoid w) => writer w (a, w -> w) -> writer w pass m = writer $ let ((a, f), w) = runwriter m in (a, f w)
it's clear listen
gives access log produced writer action inside writer monad, , pass
gives way alter log inside writer monad.
assume have writer [string]
, want log action if log produced satisfies condition:
deleteon :: (monoid w) => (w -> bool) -> writer w -> writer w deleteon p m = pass $ (a, w) <- listen m if p w return (a, id) else return (a, const mempty) -- or pass alone deleteon' :: (monoid w) => (w -> bool) -> writer w -> writer w deleteon' p m = pass $ <- m return (a, (\w -> if p w mempty else w)) logtwo :: writer [string] () logtwo = deleteon ((> 5) . length . head) $ tell ["foo"] deleteon ((> 5) . length . head) $ tell ["foobar"] {- *main> runwriter logtwo ((),["foo"]) -}
Comments
Post a Comment