[project @ 2003-06-03 22:26:44 by diatchki]
[ghc-base.git] / Control / Monad / X / ReaderT.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  Control.Monad.Reader
4 -- Copyright   :  (c) Andy Gill 2001,
5 --                (c) Oregon Graduate Institute of Science and Technology, 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  libraries@haskell.org
9 -- Stability   :  experimental
10 -- Portability :  non-portable (multi-param classes, functional dependencies)
11 --
12 -- The definition of the reader monad transformer.
13 --
14 --        Inspired by the paper
15 --        /Functional Programming with Overloading and
16 --            Higher-Order Polymorphism/, 
17 --          Mark P Jones (<http://www.cse.ogi.edu/~mpj/>)
18 --                Advanced School of Functional Programming, 1995.
19 -----------------------------------------------------------------------------
20
21 module Control.Monad.X.ReaderT (
22         ReaderT,
23         runReader,
24         runReaderT,
25         mapReaderT,
26         withReaderT,
27         module T,
28         ) where
29
30 import Prelude (Monad(..),Functor(..),const)
31 import Control.Monad (MonadPlus(..),liftM)
32
33 import Control.Monad.X.Trans as T
34 import Control.Monad.X.Utils
35 import Control.Monad.X.Types(ReaderT(..))
36
37
38
39 -- ---------------------------------------------------------------------------
40 -- Basic instances
41
42 instance MonadTrans (ReaderT r) where 
43   lift m          = R (\_ -> m) 
44
45 instance HasBaseMonad m n => HasBaseMonad (ReaderT r m) n where
46   inBase          = inBase'
47
48 instance Monad m => Functor (ReaderT r m) where
49   fmap            = liftM
50
51 instance Monad m => Monad (ReaderT r m) where
52   fail            = fail'
53   return          = return' 
54   m >>= f         = R (\r -> (m $$ r) >>= (\a -> (f a $$ r)))
55
56
57 -- some functions
58
59 -- | Remove a reader layer by providing a specific value for the 
60 -- environment.
61 runReader         :: r -> ReaderT r m a -> m a
62 runReader r m     = m $$ r
63
64 -- | Same as 'runReader' but with the arguments the other way around.
65 -- For backwards compatability.
66 runReaderT        :: ReaderT r m a -> r -> m a
67 runReaderT        = ($$)
68
69 -- | Apply a function to underlying monad.  
70 -- NOTE: SHOULD THIS BE EXPORTED?
71 mapReaderT        :: (m a -> n b) -> ReaderT w m a -> ReaderT w n b
72 mapReaderT f m    = R (\r -> f (m $$ r))
73
74 -- | A more general version of 'local' when the reader is the
75 -- outermost layer.
76 withReaderT       :: (r' -> r) -> ReaderT r m a -> ReaderT r' m a
77 withReaderT f m   = R (\r -> m $$ f r)
78
79 -- sugar.
80 ($$)              = unR
81
82
83 -- how the features are implemented for readers
84
85 instance (Monad m) => MonadReader r (ReaderT r m) where
86   ask             = R return
87   local           = withReaderT 
88
89 instance MonadWriter w m => MonadWriter w (ReaderT r m) where
90   tell            = tell'
91   listen          = listen2' R unR (\w a -> (a,w))
92
93 instance MonadState s m => MonadState s (ReaderT r m) where
94   get             = get'
95   put             = put'
96
97 instance MonadError e m => MonadError e (ReaderT r m) where
98   throwError      = throwError'
99   catchError      = catchError2' R unR
100
101 instance MonadPlus m => MonadPlus (ReaderT r m) where
102   mzero           = mzero'
103   mplus           = mplus2' R unR
104
105 instance (MonadNondet m) => MonadNondet (ReaderT r m) where
106   findAll         = mapReaderT findAll
107   commit          = mapReaderT commit 
108
109 instance MonadResume m => MonadResume (ReaderT r m) where
110   delay           = mapReaderT delay
111   force           = mapReaderT force
112
113 instance MonadCont m => MonadCont (ReaderT r m) where
114   callCC          = callCC2' R unR const 
115
116
117
118
119