tip-lib-0.1: src/Tip/Writer.hs
-- A faster implementation of the writer monad.
{-# LANGUAGE Rank2Types #-}
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
{-# INLINE fmap #-}
fmap f x = x >>= return . f
instance (Monoid w, Monad m) => Applicative (WriterT w m) where
{-# INLINE pure #-}
pure = return
{-# INLINE (<*>) #-}
(<*>) = liftM2 ($)
instance (Monoid w, Monad m) => Monad (WriterT w m) where
{-# INLINE return #-}
return x = WriterT (\k -> k mempty x)
{-# INLINE (>>=) #-}
WriterT m >>= f =
WriterT $ \k ->
m (\w x -> unWriterT (f x) (\w' y -> k (w `mappend` w') y))
{-# INLINE runWriterT #-}
runWriterT :: (Monoid w, Monad m) => WriterT w m a -> m (a, w)
runWriterT (WriterT f) = f (\w x -> return (x, w))
{-# INLINE tell #-}
tell :: (Monoid w, Monad m) => w -> WriterT w m ()
tell w = WriterT (\k -> k w ())
{-# INLINE lift #-}
lift :: (Monoid w, Monad m) => m a -> WriterT w m a
lift x = WriterT (\k -> x >>= \y -> k mempty y)
{-# INLINE censor #-}
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))