module Tip.Writer where
import Data.Monoid
import Control.Monad
import Control.Applicative
newtype WriterT w m a = WriterT { unWriterT :: forall b. (w -> a -> m b) -> m b }
instance (Monoid w, Monad m) => Functor (WriterT w m) where
fmap f x = x >>= return . f
instance (Monoid w, Monad m) => Applicative (WriterT w m) where
pure = return
(<*>) = liftM2 ($)
instance (Monoid w, Monad m) => Monad (WriterT w m) where
return x = WriterT (\k -> k mempty x)
WriterT m >>= f =
WriterT $ \k ->
m (\w x -> unWriterT (f x) (\w' y -> k (w `mappend` w') y))
runWriterT :: (Monoid w, Monad m) => WriterT w m a -> m (a, w)
runWriterT (WriterT f) = f (\w x -> return (x, w))
tell :: (Monoid w, Monad m) => w -> WriterT w m ()
tell w = WriterT (\k -> k w ())
lift :: (Monoid w, Monad m) => m a -> WriterT w m a
lift x = WriterT (\k -> x >>= \y -> k mempty y)
censor :: (Monoid w, Monad m) => (w -> w) -> WriterT w m a -> WriterT w m a
censor f (WriterT m) = WriterT (\k -> m (\w x -> k (f w) x))