{-# LANGUAGE CPP #-}{-# LANGUAGE UndecidableInstances #-}-- Search for UndecidableInstances to see why this is needed{- | Module : Control.Monad.Reader.Class Copyright : (c) Andy Gill 2001, (c) Oregon Graduate Institute of Science and Technology 2001, (c) Jeff Newbern 2003-2007, (c) Andriy Palamarchuk 2007 License : BSD-style (see the file LICENSE) Maintainer : libraries@haskell.org Stability : experimental Portability : non-portable (multi-param classes, functional dependencies) [Computation type:] Computations which read values from a shared environment. [Binding strategy:] Monad values are functions from the environment to a value. The bound function is applied to the bound value, and both have access to the shared environment. [Useful for:] Maintaining variable bindings, or other shared environment. [Zero and plus:] None. [Example type:] @'Reader' [(String,Value)] a@ The 'Reader' monad (also called the Environment monad). Represents a computation, which can read values from a shared environment, pass values from function to function, and execute sub-computations in a modified environment. Using 'Reader' monad for such computations is often clearer and easier than using the 'Control.Monad.State.State' monad. Inspired by the paper /Functional Programming with Overloading and Higher-Order Polymorphism/, Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>) Advanced School of Functional Programming, 1995. -}moduleControl.Monad.Reader.Class(MonadReader (..),asks ,)whereimportControl.Monad.Trans.ContasContimportControl.Monad.Trans.ExceptimportControl.Monad.Trans.ErrorimportControl.Monad.Trans.IdentityimportControl.Monad.Trans.ListimportControl.Monad.Trans.MaybeimportControl.Monad.Trans.Reader(ReaderT)importqualifiedControl.Monad.Trans.ReaderasReaderT(ask,local,reader)importqualifiedControl.Monad.Trans.RWS.LazyasLazyRWS(RWST,ask,local,reader)importqualifiedControl.Monad.Trans.RWS.StrictasStrictRWS(RWST,ask,local,reader)importControl.Monad.Trans.State.LazyasLazyimportControl.Monad.Trans.State.StrictasStrictimportControl.Monad.Trans.Writer.LazyasLazyimportControl.Monad.Trans.Writer.StrictasStrictimportControl.Monad.Trans.Class(lift)importControl.MonadimportData.Monoid-- ------------------------------------------------------------------------------ class MonadReader-- asks for the internal (non-mutable) state.-- | See examples in "Control.Monad.Reader".-- Note, the partially applied function type @(->) r@ is a simple reader monad.-- See the @instance@ declaration below.classMonadm =>MonadReader r m |m->rwhere#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707{-# MINIMAL (ask | reader), local #-}#endif-- | Retrieves the monad environment.ask::m r ask =reader id-- | Executes a computation in a modified environment.local::(r ->r )-- ^ The function to modify the environment.->m a -- ^ @Reader@ to run in the modified environment.->m a -- | Retrieves a function of the current environment.reader::(r ->a )-- ^ The selector function to apply to the environment.->m a reader f =dor <-ask return(f r )-- | Retrieves a function of the current environment.asks::MonadReader r m =>(r ->a )-- ^ The selector function to apply to the environment.->m a asks =reader -- ------------------------------------------------------------------------------ The partially applied function type is a simple reader monadinstanceMonadReader r ((->)r )whereask =idlocal f m =m .f reader =idinstanceMonadm =>MonadReader r (ReaderTr m )whereask =ReaderT.asklocal =ReaderT.localreader =ReaderT.readerinstance(Monadm ,Monoidw )=>MonadReader r (LazyRWS.RWSTr w s m )whereask =LazyRWS.asklocal =LazyRWS.localreader =LazyRWS.readerinstance(Monadm ,Monoidw )=>MonadReader r (StrictRWS.RWSTr w s m )whereask =StrictRWS.asklocal =StrictRWS.localreader =StrictRWS.reader-- ----------------------------------------------------------------------------- Instances for other mtl transformers---- All of these instances need UndecidableInstances,-- because they do not satisfy the coverage condition.instanceMonadReader r' m =>MonadReader r' (ContTr m )whereask =liftask local =Cont.liftLocalask local reader =lift.reader instance(Errore ,MonadReader r m )=>MonadReader r (ErrorTe m )whereask =liftask local =mapErrorT.local reader =lift.reader instanceMonadReader r m =>MonadReader r (ExceptTe m )whereask =liftask local =mapExceptT.local reader =lift.reader instanceMonadReader r m =>MonadReader r (IdentityTm )whereask =liftask local =mapIdentityT.local reader =lift.reader instanceMonadReader r m =>MonadReader r (ListTm )whereask =liftask local =mapListT.local reader =lift.reader instanceMonadReader r m =>MonadReader r (MaybeTm )whereask =liftask local =mapMaybeT.local reader =lift.reader instanceMonadReader r m =>MonadReader r (Lazy.StateTs m )whereask =liftask local =Lazy.mapStateT.local reader =lift.reader instanceMonadReader r m =>MonadReader r (Strict.StateTs m )whereask =liftask local =Strict.mapStateT.local reader =lift.reader instance(Monoidw ,MonadReader r m )=>MonadReader r (Lazy.WriterTw m )whereask =liftask local =Lazy.mapWriterT.local reader =lift.reader instance(Monoidw ,MonadReader r m )=>MonadReader r (Strict.WriterTw m )whereask =liftask local =Strict.mapWriterT.local reader =lift.reader