{-# LANGUAGE TypeFamilies, FlexibleContexts #-} {-# OPTIONS -fallow-undecidable-instances #-} -- Search for -fallow-undecidable-instances 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 libraries/base/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 () -- Advanced School of Functional Programming, 1995. ----------------------------------------------------------------------------- module Control.Monad.Writer.Class ( MonadWriter(..), listens, censor, WriterType ) where import Data.Monoid type family WriterType (m :: * -> *) -- --------------------------------------------------------------------------- -- 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 (Monoid (WriterType m), Monad m) => MonadWriter m where tell :: WriterType m -> m () listen :: m a -> m (a, WriterType m) pass :: m (a, WriterType m -> WriterType m) -> m a listens :: (MonadWriter m) => (WriterType m -> b) -> m a -> m (a, b) listens f m = do ~(a, w) <- listen m return (a, f w) censor :: (MonadWriter m) => (WriterType m -> WriterType m) -> m a -> m a censor f m = pass $ do a <- m return (a, f)