module Zinza.Writer (
Writer,
execWriter,
tell,
) where
newtype Writer a = Writer { unWriter :: ShowS -> (ShowS, a) }
execWriter :: Writer a -> String
execWriter w = fst (unWriter w id) ""
tell :: String -> Writer ()
tell x = Writer $ \s -> (s . showString x, ())
instance Functor Writer where
fmap f m = Writer $ \s -> fmap f (unWriter m s)
instance Applicative Writer where
pure x = Writer $ \s -> (s, x)
{-# INLINE pure #-}
x *> y = Writer $ \s1 ->
let (s2, _) = unWriter x s1
in unWriter y s2
{-# INLINE (*>) #-}
x <* y = Writer $ \s1 ->
let (s2, x') = unWriter x s1
(s3, _) = unWriter y s2
in (s3, x')
{-# INLINE (<*) #-}
f <*> x = Writer $ \s1 ->
let (s2, f') = unWriter f s1
(s3, x') = unWriter x s2
in (s3, f' x')
{-# INLINE (<*>) #-}
instance Monad Writer where
return = pure
{-# INLINE return #-}
(>>) = (*>)
{-# INLINE (>>) #-}
m >>= k = Writer $ \s1 ->
let (s2, x) = unWriter m s1
in unWriter (k x) s2
{-# INLINE (>>=) #-}