module Control.Eff.Writer.Lazy ( Writer(..)
, tell
, censor
, runWriter
, runFirstWriter
, runLastWriter
, runListWriter
, runMonoidWriter
) where
import Control.Eff
import Data.OpenUnion
import Data.Monoid
import Control.Applicative ((<|>))
data Writer w v = Writer w v
tell :: Member (Writer w) r => w -> Eff r ()
tell w = send $ Writer w ()
censor :: forall w a r. Member (Writer w) r => (w -> w) -> Eff r a -> Eff r a
censor f = interpose return h
where
h (Writer w v) k = tell (f w) >> k v
runWriter :: (w -> b -> b) -> b -> Eff (Writer w ': r) a -> Eff r (a, b)
runWriter accum b = handle_relay
(\x -> return (x, b))
(\(Writer w v) k -> k v >>= \(x, l) -> return (x, w `accum` l))
runListWriter :: Eff (Writer w ': r) a -> Eff r (a,[w])
runListWriter = runWriter (:) []
runMonoidWriter :: (Monoid w) => Eff (Writer w ': r) a -> Eff r (a, w)
runMonoidWriter = runWriter (<>) mempty
runFirstWriter :: Eff (Writer w ': r) a -> Eff r (a, Maybe w)
runFirstWriter = runWriter (\w b -> Just w <|> b) Nothing
runLastWriter :: Eff (Writer w ': r) a -> Eff r (a, Maybe w)
runLastWriter = runWriter (\w b -> b <|> Just w) Nothing