------------------------------------------------------------------------------- |-- Module : Control.Monad.Trans.Reader-- Copyright : (c) Andy Gill 2001,-- (c) Oregon Graduate Institute of Science and Technology, 2001-- License : BSD-style (see the file LICENSE)---- Maintainer : ross@soi.city.ac.uk-- Stability : experimental-- Portability : portable---- Declaration of the 'ReaderT' monad transformer, which adds a static-- environment to a given monad.---- If the computation is to modify the stored information, use-- "Control.Monad.Trans.State" instead.-----------------------------------------------------------------------------moduleControl.Monad.Trans.Reader(-- * The Reader monadReader,reader,runReader,mapReader,withReader,-- * The ReaderT monad transformerReaderT(..),mapReaderT,withReaderT,-- * Reader operationsask,local,asks,-- * Lifting other operationsliftCallCC,liftCatch,)whereimportControl.Monad.IO.ClassimportControl.Monad.Trans.ClassimportData.Functor.IdentityimportControl.ApplicativeimportControl.MonadimportControl.Monad.FiximportControl.Monad.Instances()-- | The parameterizable reader monad.---- Computations are functions of a shared environment.---- The 'return' function ignores the environment, while @>>=@ passes-- the inherited environment to both subcomputations.typeReaderr=ReaderTrIdentity-- | Constructor for computations in the reader monad.reader::(r->a)->Readerrareaderf=ReaderT(Identity.f)-- | Runs a @Reader@ and extracts the final value from it.runReader::Readerra-- ^ A @Reader@ to run.->r-- ^ An initial environment.->arunReaderm=runIdentity.runReaderTm-- | Transform the value returned by a @Reader@.mapReader::(a->b)->Readerra->ReaderrbmapReaderf=mapReaderT(Identity.f.runIdentity)-- | Execute a computation in a modified environment-- (a specialization of 'withReaderT').withReader::(r'->r)-- ^ The function to modify the environment.->Readerra-- ^ Computation to run in the modified environment.->Readerr'awithReader=withReaderT-- | The reader monad transformer,-- which adds a read-only environment to the given monad.---- The 'return' function ignores the environment, while @>>=@ passes-- the inherited environment to both subcomputations.newtypeReaderTrma=ReaderT{-- | The underlying computation, as a function of the environment.runReaderT::r->ma}-- | Transform the computation inside a @ReaderT@.mapReaderT::(ma->nb)->ReaderTrma->ReaderTrnbmapReaderTfm=ReaderT$f.runReaderTm-- | Execute a computation in a modified environment-- (a more general version of 'local').withReaderT::(r'->r)-- ^ The function to modify the environment.->ReaderTrma-- ^ Computation to run in the modified environment.->ReaderTr'mawithReaderTfm=ReaderT$runReaderTm.finstance(Functorm)=>Functor(ReaderTrm)wherefmapf=mapReaderT(fmapf)instance(Applicativem)=>Applicative(ReaderTrm)wherepure=liftReaderT.puref<*>v=ReaderT$\r->runReaderTfr<*>runReaderTvrinstance(Alternativem)=>Alternative(ReaderTrm)whereempty=liftReaderTemptym<|>n=ReaderT$\r->runReaderTmr<|>runReaderTnrinstance(Monadm)=>Monad(ReaderTrm)wherereturn=lift.returnm>>=k=ReaderT$\r->doa<-runReaderTmrrunReaderT(ka)rfailmsg=lift(failmsg)instance(MonadPlusm)=>MonadPlus(ReaderTrm)wheremzero=liftmzerom`mplus`n=ReaderT$\r->runReaderTmr`mplus`runReaderTnrinstance(MonadFixm)=>MonadFix(ReaderTrm)wheremfixf=ReaderT$\r->mfix$\a->runReaderT(fa)rinstanceMonadTrans(ReaderTr)wherelift=liftReaderTinstance(MonadIOm)=>MonadIO(ReaderTrm)whereliftIO=lift.liftIOliftReaderT::ma->ReaderTrmaliftReaderTm=ReaderT(constm)-- | Fetch the value of the environment.ask::(Monadm)=>ReaderTrmrask=ReaderTreturn-- | Execute a computation in a modified environment-- (a specialization of 'withReaderT').local::(Monadm)=>(r->r)-- ^ The function to modify the environment.->ReaderTrma-- ^ Computation to run in the modified environment.->ReaderTrmalocal=withReaderT-- | Retrieve a function of the current environment.asks::(Monadm)=>(r->a)-- ^ The selector function to apply to the environment.->ReaderTrmaasksf=liftMfask-- | Lift a @callCC@ operation to the new monad.liftCallCC::(((a->mb)->ma)->ma)-- ^ @callCC@ on the argument monad.->((a->ReaderTrmb)->ReaderTrma)->ReaderTrmaliftCallCCcallCCf=ReaderT$\r->callCC$\c->runReaderT(f(ReaderT.const.c))r-- | Lift a @catchError@ operation to the new monad.liftCatch::(ma->(e->ma)->ma)-- ^ @catch@ on the argument monad.->ReaderTrma-- ^ Computation to attempt.->(e->ReaderTrma)-- ^ Exception handler.->ReaderTrmaliftCatchfmh=ReaderT$\r->f(runReaderTmr)(\e->runReaderT(he)r)