instance MonadReader r m => MonadReader r (ExceptT e m)
[packages/mtl.git] / Control / Monad / Reader / Class.hs
1 {-# LANGUAGE UndecidableInstances #-}
2 -- Search for UndecidableInstances to see why this is needed
3 {- |
4 Module : Control.Monad.Reader.Class
5 Copyright : (c) Andy Gill 2001,
6 (c) Oregon Graduate Institute of Science and Technology 2001,
7 (c) Jeff Newbern 2003-2007,
8 (c) Andriy Palamarchuk 2007
9 License : BSD-style (see the file LICENSE)
10
11 Maintainer : libraries@haskell.org
12 Stability : experimental
13 Portability : non-portable (multi-param classes, functional dependencies)
14
15 [Computation type:] Computations which read values from a shared environment.
16
17 [Binding strategy:] Monad values are functions from the environment to a value.
18 The bound function is applied to the bound value, and both have access
19 to the shared environment.
20
21 [Useful for:] Maintaining variable bindings, or other shared environment.
22
23 [Zero and plus:] None.
24
25 [Example type:] @'Reader' [(String,Value)] a@
26
27 The 'Reader' monad (also called the Environment monad).
28 Represents a computation, which can read values from
29 a shared environment, pass values from function to function,
30 and execute sub-computations in a modified environment.
31 Using 'Reader' monad for such computations is often clearer and easier
32 than using the 'Control.Monad.State.State' monad.
33
34 Inspired by the paper
35 /Functional Programming with Overloading and Higher-Order Polymorphism/,
36 Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
37 Advanced School of Functional Programming, 1995.
38 -}
39
40 module Control.Monad.Reader.Class (
41 MonadReader(..),
42 asks,
43 ) where
44
45 import Control.Monad.Trans.Cont as Cont
46 import Control.Monad.Trans.Except
47 import Control.Monad.Trans.Error
48 import Control.Monad.Trans.Identity
49 import Control.Monad.Trans.List
50 import Control.Monad.Trans.Maybe
51 import Control.Monad.Trans.Reader (ReaderT)
52 import qualified Control.Monad.Trans.Reader as ReaderT (ask, local, reader)
53 import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, ask, local, reader)
54 import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, ask, local, reader)
55 import Control.Monad.Trans.State.Lazy as Lazy
56 import Control.Monad.Trans.State.Strict as Strict
57 import Control.Monad.Trans.Writer.Lazy as Lazy
58 import Control.Monad.Trans.Writer.Strict as Strict
59
60 import Control.Monad.Trans.Class (lift)
61 import Control.Monad
62 import Data.Monoid
63
64 -- ----------------------------------------------------------------------------
65 -- class MonadReader
66 -- asks for the internal (non-mutable) state.
67
68 -- | See examples in "Control.Monad.Reader".
69 -- Note, the partially applied function type @(->) r@ is a simple reader monad.
70 -- See the @instance@ declaration below.
71 class Monad m => MonadReader r m | m -> r where
72 -- | Retrieves the monad environment.
73 ask :: m r
74
75 -- | Executes a computation in a modified environment.
76 local :: (r -> r) -- ^ The function to modify the environment.
77 -> m a -- ^ @Reader@ to run in the modified environment.
78 -> m a
79
80 -- | Retrieves a function of the current environment.
81 reader :: (r -> a) -- ^ The selector function to apply to the environment.
82 -> m a
83 reader f = do
84 r <- ask
85 return (f r)
86
87 -- | Retrieves a function of the current environment.
88 asks :: MonadReader r m
89 => (r -> a) -- ^ The selector function to apply to the environment.
90 -> m a
91 asks = reader
92
93 -- ----------------------------------------------------------------------------
94 -- The partially applied function type is a simple reader monad
95
96 instance MonadReader r ((->) r) where
97 ask = id
98 local f m = m . f
99 reader = id
100
101 instance Monad m => MonadReader r (ReaderT r m) where
102 ask = ReaderT.ask
103 local = ReaderT.local
104 reader = ReaderT.reader
105
106 instance (Monad m, Monoid w) => MonadReader r (LazyRWS.RWST r w s m) where
107 ask = LazyRWS.ask
108 local = LazyRWS.local
109 reader = LazyRWS.reader
110
111 instance (Monad m, Monoid w) => MonadReader r (StrictRWS.RWST r w s m) where
112 ask = StrictRWS.ask
113 local = StrictRWS.local
114 reader = StrictRWS.reader
115
116 -- ---------------------------------------------------------------------------
117 -- Instances for other mtl transformers
118 --
119 -- All of these instances need UndecidableInstances,
120 -- because they do not satisfy the coverage condition.
121
122 instance MonadReader r' m => MonadReader r' (ContT r m) where
123 ask = lift ask
124 local = Cont.liftLocal ask local
125 reader = lift . reader
126
127 instance (Error e, MonadReader r m) => MonadReader r (ErrorT e m) where
128 ask = lift ask
129 local = mapErrorT . local
130 reader = lift . reader
131
132 instance MonadReader r m => MonadReader r (ExceptT e m) where
133 ask = lift ask
134 local = mapExceptT . local
135 reader = lift . reader
136
137 instance MonadReader r m => MonadReader r (IdentityT m) where
138 ask = lift ask
139 local = mapIdentityT . local
140 reader = lift . reader
141
142 instance MonadReader r m => MonadReader r (ListT m) where
143 ask = lift ask
144 local = mapListT . local
145 reader = lift . reader
146
147 instance MonadReader r m => MonadReader r (MaybeT m) where
148 ask = lift ask
149 local = mapMaybeT . local
150 reader = lift . reader
151
152 instance MonadReader r m => MonadReader r (Lazy.StateT s m) where
153 ask = lift ask
154 local = Lazy.mapStateT . local
155 reader = lift . reader
156
157 instance MonadReader r m => MonadReader r (Strict.StateT s m) where
158 ask = lift ask
159 local = Strict.mapStateT . local
160 reader = lift . reader
161
162 instance (Monoid w, MonadReader r m) => MonadReader r (Lazy.WriterT w m) where
163 ask = lift ask
164 local = Lazy.mapWriterT . local
165 reader = lift . reader
166
167 instance (Monoid w, MonadReader r m) => MonadReader r (Strict.WriterT w m) where
168 ask = lift ask
169 local = Strict.mapWriterT . local
170 reader = lift . reader