idris-0.9.10: libs/base/Control/Monad/Writer.idr
module Control.Monad.Writer
import Builtins
import Control.Monad.Identity
%access public
class (Monoid w, Monad m) => MonadWriter w (m : Type -> Type) where
tell : w -> m ()
listen : m a -> m (a, w)
pass : m (a, w -> w) -> m a
record WriterT : Type -> (Type -> Type) -> Type -> Type where
WR : {m : Type -> Type} ->
(runWriterT : m (a, w)) -> WriterT w m a
instance Functor f => Functor (WriterT w f) where
map f (WR g) = WR $ map (\w => (f . fst $ w, snd w)) g
instance (Monoid w, Applicative m) => Applicative (WriterT w m) where
pure a = WR $ pure (a, neutral)
(WR f) <$> (WR v) = WR $ liftA2 merge f v where
merge (fn, w) (a, w') = (fn a, w <+> w')
instance (Monoid w, Alternative m) => Alternative (WriterT w m) where
empty = WR empty
(WR m) <|> (WR n) = WR $ m <|> n
instance (Monoid w, Monad m) => Monad (WriterT w m) where
(WR m) >>= k = WR $ do (a, w) <- m
let WR ka = k a
(b, w') <- ka
return (b, w <+> w')
instance (Monoid w, Monad m) => MonadWriter w (WriterT w m) where
tell w = WR $ return ((), w)
listen (WR m) = WR $ do (a, w) <- m
return ((a, w), w)
pass (WR m) = WR $ do ((a, f), w) <- m
return (a, f w)
listens : MonadWriter w m => (w -> b) -> m a -> m (a, b)
listens f m = listens' f (listen m) where
listens' f' ma = do (a, w) <- ma
return (a, f' w)
censor : MonadWriter w m => (w -> w) -> m a -> m a
censor f m = pass $ do a <- m
return (a, f)
Writer : Type -> Type -> Type
Writer w a = WriterT w Identity a