{-# LANGUAGE CPP #-}{-# LANGUAGE UndecidableInstances #-}-- Search for UndecidableInstances to see why this is needed------------------------------------------------------------------------------- |-- Module : Control.Monad.Writer.Class-- Copyright : (c) Andy Gill 2001,-- (c) Oregon Graduate Institute of Science and Technology, 2001-- License : BSD-style (see the file LICENSE)---- Maintainer : libraries@haskell.org-- Stability : experimental-- Portability : non-portable (multi-param classes, functional dependencies)---- The MonadWriter class.---- Inspired by the paper-- /Functional Programming with Overloading and Higher-Order Polymorphism/,-- Mark P Jones (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>)-- Advanced School of Functional Programming, 1995.-----------------------------------------------------------------------------moduleControl.Monad.Writer.Class(MonadWriter (..),listens ,censor ,)whereimportControl.Monad.Trans.ErrorasErrorimportControl.Monad.Trans.ExceptasExceptimportControl.Monad.Trans.IdentityasIdentityimportControl.Monad.Trans.MaybeasMaybeimportControl.Monad.Trans.ReaderimportqualifiedControl.Monad.Trans.RWS.LazyasLazyRWS(RWST,writer,tell,listen,pass)importqualifiedControl.Monad.Trans.RWS.StrictasStrictRWS(RWST,writer,tell,listen,pass)importControl.Monad.Trans.State.LazyasLazyimportControl.Monad.Trans.State.StrictasStrictimportqualifiedControl.Monad.Trans.Writer.LazyasLazy(WriterT,writer,tell,listen,pass)importqualifiedControl.Monad.Trans.Writer.StrictasStrict(WriterT,writer,tell,listen,pass)importControl.Monad.Trans.Class(lift)importControl.MonadimportData.Monoid-- ----------------------------------------------------------------------------- MonadWriter class---- tell is like tell on the MUD's it shouts to monad-- what you want to be heard. The monad carries this 'packet'-- upwards, merging it if needed (hence the Monoid requirement).---- listen listens to a monad acting, and returns what the monad "said".---- pass lets you provide a writer transformer which changes internals of-- the written object.class(Monoidw ,Monadm )=>MonadWriter w m |m->wwhere#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707{-# MINIMAL (writer | tell), listen, pass #-}#endif-- | @'writer' (a,w)@ embeds a simple writer action.writer::(a ,w )->m a writer ~(a ,w )=dotell w returna -- | @'tell' w@ is an action that produces the output @w@.tell::w ->m ()tell w =writer ((),w )-- | @'listen' m@ is an action that executes the action @m@ and adds-- its output to the value of the computation.listen::m a ->m (a ,w )-- | @'pass' m@ is an action that executes the action @m@, which-- returns a value and a function, and returns the value, applying-- the function to the output.pass::m (a ,w ->w )->m a -- | @'listens' f m@ is an action that executes the action @m@ and adds-- the result of applying @f@ to the output to the value of the computation.---- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@listens::MonadWriter w m =>(w ->b )->m a ->m (a ,b )listens f m =do~(a ,w )<-listen m return(a ,f w )-- | @'censor' f m@ is an action that executes the action @m@ and-- applies the function @f@ to its output, leaving the return value-- unchanged.---- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@censor::MonadWriter w m =>(w ->w )->m a ->m a censor f m =pass $doa <-m return(a ,f )instance(Monoidw ,Monadm )=>MonadWriter w (Lazy.WriterTw m )wherewriter =Lazy.writertell =Lazy.telllisten =Lazy.listenpass =Lazy.passinstance(Monoidw ,Monadm )=>MonadWriter w (Strict.WriterTw m )wherewriter =Strict.writertell =Strict.telllisten =Strict.listenpass =Strict.passinstance(Monoidw ,Monadm )=>MonadWriter w (LazyRWS.RWSTr w s m )wherewriter =LazyRWS.writertell =LazyRWS.telllisten =LazyRWS.listenpass =LazyRWS.passinstance(Monoidw ,Monadm )=>MonadWriter w (StrictRWS.RWSTr w s m )wherewriter =StrictRWS.writertell =StrictRWS.telllisten =StrictRWS.listenpass =StrictRWS.pass-- ----------------------------------------------------------------------------- Instances for other mtl transformers---- All of these instances need UndecidableInstances,-- because they do not satisfy the coverage condition.instance(Errore ,MonadWriter w m )=>MonadWriter w (ErrorTe m )wherewriter =lift.writer tell =lift.tell listen =Error.liftListenlisten pass =Error.liftPasspass instanceMonadWriter w m =>MonadWriter w (ExceptTe m )wherewriter =lift.writer tell =lift.tell listen =Except.liftListenlisten pass =Except.liftPasspass instanceMonadWriter w m =>MonadWriter w (IdentityTm )wherewriter =lift.writer tell =lift.tell listen =Identity.mapIdentityTlisten pass =Identity.mapIdentityTpass instanceMonadWriter w m =>MonadWriter w (MaybeTm )wherewriter =lift.writer tell =lift.tell listen =Maybe.liftListenlisten pass =Maybe.liftPasspass instanceMonadWriter w m =>MonadWriter w (ReaderTr m )wherewriter =lift.writer tell =lift.tell listen =mapReaderTlisten pass =mapReaderTpass instanceMonadWriter w m =>MonadWriter w (Lazy.StateTs m )wherewriter =lift.writer tell =lift.tell listen =Lazy.liftListenlisten pass =Lazy.liftPasspass instanceMonadWriter w m =>MonadWriter w (Strict.StateTs m )wherewriter =lift.writer tell =lift.tell listen =Strict.liftListenlisten pass =Strict.liftPasspass