module Control.Eff.Writer.Lazy( Writer (..)
, tell
, censor
, runWriter
, runFirstWriter
, runLastWriter
, runMonoidWriter
) where
import Data.Typeable
import Control.Applicative ((<|>))
import Data.Monoid
import Control.Eff
data Writer w v = Writer w v
deriving (Typeable, Functor)
tell :: (Typeable w, Member (Writer w) r) => w -> Eff r ()
tell w = send . inj $ Writer w ()
censor :: (Typeable w, Member (Writer w) r) => (w -> w) -> Eff r a -> Eff r a
censor f = loop
where
loop = freeMap
return
(\u -> interpose u loop
$ \(Writer w v) -> tell (f w) >> loop v)
runWriter :: Typeable w => (w -> b -> b) -> b -> Eff (Writer w :> r) a -> Eff r (b, a)
runWriter accum b = loop
where
first f (x, y) = (f x, y)
loop = freeMap
(\x -> return (b, x))
(\u -> handleRelay u loop
$ \(Writer w v) -> first (accum w) `fmap` loop v)
runFirstWriter :: Typeable w => Eff (Writer w :> r) a -> Eff r (Maybe w, a)
runFirstWriter = runWriter (\w b -> Just w <|> b) Nothing
runLastWriter :: Typeable w => Eff (Writer w :> r) a -> Eff r (Maybe w, a)
runLastWriter = runWriter (\w b -> b <|> Just w) Nothing
runMonoidWriter :: (Monoid w, Typeable w) => Eff (Writer w :> r) a -> Eff r (w, a)
runMonoidWriter = runWriter (<>) mempty