# Ticket #1410: ReaderMonad.patch

File ReaderMonad.patch, 10.5 KB (added by , 10 years ago) |
---|

Line | |
---|---|

1 | |

2 | New patches: |

3 | |

4 | [Reader Monad. Added Haddock documentation. Converted the existing module documentation to Haddock format. Created examples. Per Jeff Newberns permission included parts his tutorial "All About Monads" http://haskell.org/all_about_monads/. |

5 | Andriy Palamarchuk <apa3a@yahoo.com>**20070627180520] { |

6 | hunk ./Control/Monad/Reader/Class.hs 2 |

7 | --- Search for -fallow-undecidable-instances to see why this is needed |

8 | ------------------------------------------------------------------------------ |

9 | --- | |

10 | --- Module : Control.Monad.Reader.Class |

11 | --- Copyright : (c) Andy Gill 2001, |

12 | --- (c) Oregon Graduate Institute of Science and Technology, 2001 |

13 | --- License : BSD-style (see the file libraries/base/LICENSE) |

14 | --- |

15 | --- Maintainer : libraries@haskell.org |

16 | --- Stability : experimental |

17 | --- Portability : non-portable (multi-param classes, functional dependencies) |

18 | --- |

19 | --- MonadReader class. |

20 | --- |

21 | --- Inspired by the paper |

22 | --- /Functional Programming with Overloading and |

23 | --- Higher-Order Polymorphism/, |

24 | --- Mark P Jones (<http://www.cse.ogi.edu/~mpj/>) |

25 | --- Advanced School of Functional Programming, 1995. |

26 | ------------------------------------------------------------------------------ |

27 | +{- | |

28 | +Module : Control.Monad.Reader.Class |

29 | +Copyright : (c) Andy Gill 2001, |

30 | + (c) Oregon Graduate Institute of Science and Technology 2001, |

31 | + (c) Jeff Newbern 2003-2007, |

32 | + (c) Andriy Palamarchuk 2007 |

33 | +License : BSD-style (see the file libraries/base/LICENSE) |

34 | + |

35 | +Maintainer : libraries@haskell.org |

36 | +Stability : experimental |

37 | +Portability : non-portable (multi-param classes, functional dependencies) |

38 | + |

39 | +[Computation type:] Computations which read values from a shared environment. |

40 | + |

41 | +[Binding strategy:] Monad values are functions from the environment to a value. |

42 | +The bound function is applied to the bound value, and both have access |

43 | +to the shared environment. |

44 | + |

45 | +[Useful for:] Maintaining variable bindings, or other shared environment. |

46 | + |

47 | +[Zero and plus:] None. |

48 | + |

49 | +[Example type:] @'Reader' [(String,Value)] a@ |

50 | + |

51 | +The 'Reader' monad (also called the Environment monad). |

52 | +Represents a computation, which can read values from |

53 | +a shared environment, pass values from function to function, |

54 | +and execute sub-computations in a modified environment. |

55 | +Using 'Reader' monad for such computations is often clearer and easier |

56 | +than using the 'Control.Monad.State.State' monad. |

57 | + |

58 | + Inspired by the paper |

59 | + /Functional Programming with Overloading and |

60 | + Higher-Order Polymorphism/, |

61 | + Mark P Jones (<http://www.cse.ogi.edu/~mpj/>) |

62 | + Advanced School of Functional Programming, 1995. |

63 | +-} |

64 | hunk ./Control/Monad/Reader/Class.hs 45 |

65 | --- ---------------------------------------------------------------------------- |

66 | --- class MonadReader |

67 | --- asks for the internal (non-mutable) state. |

68 | - |

69 | +{- | |

70 | +See examples in "Control.Monad.Reader". |

71 | +Note, the partially applied function type @(->) r@ is a simple reader monad. |

72 | +See the @instance@ declaration below. |

73 | +-} |

74 | hunk ./Control/Monad/Reader/Class.hs 51 |

75 | + -- | Retrieves the monad environment. |

76 | hunk ./Control/Monad/Reader/Class.hs 53 |

77 | + {- | Executes a computation in a modified environment. Parameters: |

78 | + |

79 | + * The function to modify the environment. |

80 | + |

81 | + * @Reader@ to run. |

82 | + |

83 | + * The resulting @Reader@. |

84 | + -} |

85 | hunk ./Control/Monad/Reader/Class.hs 63 |

86 | --- This allows you to provide a projection function. |

87 | +{- | |

88 | +Retrieves a function of the current environment. Parameters: |

89 | + |

90 | +* The selector function to apply to the environment. |

91 | hunk ./Control/Monad/Reader/Class.hs 68 |

92 | +See an example in "Control.Monad.Reader". |

93 | +-} |

94 | hunk ./Control/Monad/Reader.hs 2 |

95 | --- Search for -fallow-undecidable-instances to see why this is needed |

96 | ------------------------------------------------------------------------------ |

97 | --- | |

98 | --- Module : Control.Monad.Reader |

99 | --- Copyright : (c) Andy Gill 2001, |

100 | --- (c) Oregon Graduate Institute of Science and Technology, 2001 |

101 | --- License : BSD-style (see the file libraries/base/LICENSE) |

102 | --- |

103 | --- Maintainer : libraries@haskell.org |

104 | --- Stability : experimental |

105 | --- Portability : non-portable (multi-param classes, functional dependencies) |

106 | --- |

107 | --- Declaration of the MonadReader class |

108 | --- |

109 | --- Inspired by the paper |

110 | --- /Functional Programming with Overloading and |

111 | --- Higher-Order Polymorphism/, |

112 | --- Mark P Jones (<http://www.cse.ogi.edu/~mpj/>) |

113 | --- Advanced School of Functional Programming, 1995. |

114 | ------------------------------------------------------------------------------ |

115 | +{- | |

116 | +Module : Control.Monad.Reader |

117 | +Copyright : (c) Andy Gill 2001, |

118 | + (c) Oregon Graduate Institute of Science and Technology 2001, |

119 | + (c) Jeff Newbern 2003-2007, |

120 | + (c) Andriy Palamarchuk 2007 |

121 | +License : BSD-style (see the file libraries/base/LICENSE) |

122 | + |

123 | +Maintainer : libraries@haskell.org |

124 | +Stability : experimental |

125 | +Portability : non-portable (multi-param classes, functional dependencies) |

126 | + |

127 | +[Computation type:] Computations which read values from a shared environment. |

128 | + |

129 | +[Binding strategy:] Monad values are functions from the environment to a value. |

130 | +The bound function is applied to the bound value, and both have access |

131 | +to the shared environment. |

132 | + |

133 | +[Useful for:] Maintaining variable bindings, or other shared environment. |

134 | + |

135 | +[Zero and plus:] None. |

136 | + |

137 | +[Example type:] @'Reader' [(String,Value)] a@ |

138 | + |

139 | +The 'Reader' monad (also called the Environment monad). |

140 | +Represents a computation, which can read values from |

141 | +a shared environment, pass values from function to function, |

142 | +and execute sub-computations in a modified environment. |

143 | +Using 'Reader' monad for such computations is often clearer and easier |

144 | +than using the 'Control.Monad.State.State' monad. |

145 | + |

146 | + Inspired by the paper |

147 | + /Functional Programming with Overloading and |

148 | + Higher-Order Polymorphism/, |

149 | + Mark P Jones (<http://www.cse.ogi.edu/~mpj/>) |

150 | + Advanced School of Functional Programming, 1995. |

151 | +-} |

152 | hunk ./Control/Monad/Reader.hs 51 |

153 | + -- * Example 1: Simple Reader Usage |

154 | + -- $simpleReaderExample |

155 | + |

156 | + -- * Example 2: Modifying Reader Content With @local@ |

157 | + -- $localExample |

158 | + |

159 | + -- * Example 3: @ReaderT@ Monad Transformer |

160 | + -- $ReaderTExample |

161 | hunk ./Control/Monad/Reader.hs 78 |

162 | --- --------------------------------------------------------------------------- |

163 | --- Our parameterizable reader monad |

164 | +{- | |

165 | +The parameterizable reader monad. |

166 | + |

167 | +The @return@ function creates a @Reader@ that ignores the environment, |

168 | +and produces the given value. |

169 | hunk ./Control/Monad/Reader.hs 84 |

170 | -newtype Reader r a = Reader { runReader :: r -> a } |

171 | +The binding operator @>>=@ produces a @Reader@ that uses the environment |

172 | +to extract the value its left-hand side, |

173 | +and then applies the bound function to that value in the same environment. |

174 | +-} |

175 | +newtype Reader r a = Reader { |

176 | + {- | |

177 | + Runs @Reader@ and extracts the final value from it. |

178 | + To extract the value apply @(runReader reader)@ to an environment value. |

179 | + Parameters: |

180 | + |

181 | + * A @Reader@ to run. |

182 | + |

183 | + * An initial environment. |

184 | + -} |

185 | + runReader :: r -> a |

186 | +} |

187 | hunk ./Control/Monad/Reader.hs 104 |

188 | --- This is a more general version of local. |

189 | +-- | A more general version of 'local'. |

190 | hunk ./Control/Monad/Reader.hs 123 |

191 | --- --------------------------------------------------------------------------- |

192 | --- Our parameterizable reader monad, with an inner monad |

193 | - |

194 | +{- | |

195 | +The reader monad transformer. |

196 | +Can be used to add environment reading functionality to other monads. |

197 | +-} |

198 | hunk ./Control/Monad/Reader.hs 189 |

199 | +{- $simpleReaderExample |

200 | + |

201 | +In this example the @Reader@ monad provides access to variable bindings. |

202 | +Bindings are a 'Map' of integer variables. |

203 | +The variable @count@ contains number of variables in the bindings. |

204 | +You can see how to run a Reader monad and retrieve data from it |

205 | +with 'runReader', how to access the Reader data with 'ask' and 'asks'. |

206 | + |

207 | +> type Bindings = Map String Int; |

208 | +> |

209 | +>-- Returns True if the "count" variable contains correct bindings size. |

210 | +>isCountCorrect :: Bindings -> Bool |

211 | +>isCountCorrect bindings = runReader calc_isCountCorrect bindings |

212 | +> |

213 | +>-- The Reader monad, which implements this complicated check. |

214 | +>calc_isCountCorrect :: Reader Bindings Bool |

215 | +>calc_isCountCorrect = do |

216 | +> count <- asks (lookupVar "count") |

217 | +> bindings <- ask |

218 | +> return (count == (Map.size bindings)) |

219 | +> |

220 | +>-- The selector function to use with 'asks'. |

221 | +>-- Returns value of the variable with specified name. |

222 | +>lookupVar :: String -> Bindings -> Int |

223 | +>lookupVar name bindings = fromJust (Map.lookup name bindings) |

224 | +> |

225 | +>sampleBindings = Map.fromList [("count",3), ("1",1), ("b",2)] |

226 | +> |

227 | +>main = do |

228 | +> putStr $ "Count is correct for bindings " ++ (show sampleBindings) ++ ": "; |

229 | +> putStrLn $ show (isCountCorrect sampleBindings); |

230 | +-} |

231 | + |

232 | +{- $localExample |

233 | + |

234 | +Shows how to modify Reader content with 'local'. |

235 | + |

236 | +>calculateContentLen :: Reader String Int |

237 | +>calculateContentLen = do |

238 | +> content <- ask |

239 | +> return (length content); |

240 | +> |

241 | +>-- Calls calculateContentLen after adding a prefix to the Reader content. |

242 | +>calculateModifiedContentLen :: Reader String Int |

243 | +>calculateModifiedContentLen = local ("Prefix " ++) calculateContentLen |

244 | +> |

245 | +>main = do |

246 | +> let s = "12345"; |

247 | +> let modifiedLen = runReader calculateModifiedContentLen s |

248 | +> let len = runReader calculateContentLen s |

249 | +> putStrLn $ "Modified 's' length: " ++ (show modifiedLen) |

250 | +> putStrLn $ "Original 's' length: " ++ (show len) |

251 | +-} |

252 | + |

253 | +{- $ReaderTExample |

254 | + |

255 | +Now you are thinking: 'Wow, what a great monad! I wish I could use |

256 | +Reader functionality in MyFavoriteComplexMonad!'. Don't worry. |

257 | +This can be easy done with the 'ReaderT' monad transformer. |

258 | +This example shows how to combine @ReaderT@ with the IO monad. |

259 | + |

260 | +>-- The Reader/IO combined monad, where Reader stores a string. |

261 | +>printReaderContent :: ReaderT String IO () |

262 | +>printReaderContent = do |

263 | +> content <- ask |

264 | +> liftIO $ putStrLn ("The Reader Content: " ++ content) |

265 | +> |

266 | +>main = do |

267 | +> runReaderT printReaderContent "Some Content" |

268 | +-} |

269 | } |

270 | |

271 | Context: |

272 | |

273 | [--configure-option and --ghc-option are now provided by Cabal |

274 | Ross Paterson <ross@soi.city.ac.uk>**20070604115936] |

275 | [Added Haddock documentation. Converted the existing module documentation to Haddock format. Created examples. Per Jeff Newberns permission included parts his tutorial "All About Monads" http://haskell.org/all_about_monads/. |

276 | Andriy Palamarchuk <apa3a@yahoo.com>**20070604133602] |

277 | [Remove Makefile and package.conf.in (used in the old GHC build system) |

278 | Ian Lynagh <igloo@earth.li>**20070524145902] |

279 | [TAG GHC 6.6.1 release |

280 | Ian Lynagh <igloo@earth.li>**20070428195851] |

281 | Patch bundle hash: |

282 | cd548a35478049f88040e67250c9d9d853d6fa8f |