-- | 'MSF's with a 'Writer' monadic layer. -- -- This module contains functions to work with 'MSF's that include a 'Writer' -- monadic layer. This includes functions to create new 'MSF's that include an -- additional layer, and functions to flatten that layer out of the 'MSF`'s -- transformer stack. -- -- It is based on the _strict_ writer monad 'Control.Monad.Trans.Writer.Strict', -- so when combining it with other modules such as @mtl@'s, -- the strict version has to be included, i.e. 'Control.Monad.Writer.Strict' -- instead of 'Control.Monad.Writer' or 'Control.Monad.Writer.Lazy'. module Control.Monad.Trans.MSF.Writer ( module Control.Monad.Trans.Writer.Strict -- * 'Writer' 'MSF' running and wrapping , writerS , runWriterS ) where -- External import Control.Monad.Trans.Writer.Strict hiding (liftCallCC, liftCatch, pass) -- Avoid conflicting exports import Data.Functor ((<$>)) import Data.Monoid -- Internal import Data.MonadicStreamFunction -- * 'Writer' 'MSF' running and wrapping -- | Build an 'MSF' in the 'Writer' monad from one that produces the log as an -- extra output. This is the opposite of 'runWriterS'. writerS :: (Functor m, Monad m, Monoid w) => MSF m a (w, b) -> MSF (WriterT w m) a b writerS = morphGS $ \f a -> WriterT $ (\((w, b), c) -> ((b, c), w)) <$> f a -- | Build an 'MSF' that produces the log as an extra output from one on the -- 'Writer' monad. This is the opposite of 'writerS'. runWriterS :: (Functor m, Monad m) => MSF (WriterT s m) a b -> MSF m a (s, b) runWriterS = morphGS $ \f a -> (\((b, c), s) -> ((s, b), c)) <$> runWriterT (f a)