# Ticket #4315: GeneralizeRandomAndRandomGen.patch

File GeneralizeRandomAndRandomGen.patch, 8.6 KB (added by TomMD, 4 years ago) |
---|

Line | |
---|---|

1 | 1 patch for repository /home/tommd/dev/Haskell/HaskellCommunity/random: |

2 | |

3 | Tue Sep 14 16:30:58 PDT 2010 thomas.dubuisson@gmail.com |

4 | * Generalize RandomGen and Random by generated type |

5 | |

6 | New patches: |

7 | |

8 | [Generalize RandomGen and Random by generated type |

9 | thomas.dubuisson@gmail.com**20100914233058 |

10 | Ignore-this: 19d665fd3764ed8652827da9f666f78e |

11 | ] { |

12 | hunk ./System/Random.hs 1 |

13 | +{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FunctionalDependencies #-} |

14 | ----------------------------------------------------------------------------- |

15 | -- | |

16 | -- Module : System.Random |

17 | hunk ./System/Random.hs 62 |

18 | |

19 | -- * Random values of various types |

20 | , Random ( random, randomR, |

21 | - randoms, randomRs, |

22 | - randomIO, randomRIO ) |

23 | + randoms, randomRs ) |

24 | + , randomIO |

25 | + , randomRIO |

26 | |

27 | -- * References |

28 | -- $references |

29 | hunk ./System/Random.hs 106 |

30 | |

31 | -- | The class 'RandomGen' provides a common interface to random number |

32 | -- generators. |

33 | --- |

34 | --- Minimal complete definition: 'next'. |

35 | |

36 | hunk ./System/Random.hs 107 |

37 | -class RandomGen g where |

38 | +class RandomGen g v | g -> v where |

39 | |

40 | hunk ./System/Random.hs 109 |

41 | - -- |The 'next' operation returns an 'Int' that is uniformly distributed |

42 | + -- |The 'next' operation returns a value that is uniformly distributed |

43 | -- in the range returned by 'genRange' (including both end points), |

44 | -- and a new generator. |

45 | hunk ./System/Random.hs 112 |

46 | - next :: g -> (Int, g) |

47 | + next :: g -> (v, g) |

48 | |

49 | -- |The 'genRange' operation yields the range of values returned by |

50 | -- the generator. |

51 | hunk ./System/Random.hs 119 |

52 | -- |

53 | -- It is required that: |

54 | -- |

55 | - -- * If @(a,b) = 'genRange' g@, then @a < b@. |

56 | + -- * If @(a,b) = 'genRange' g@ and v is of the Ord class, then @a < b@. |

57 | -- |

58 | hunk ./System/Random.hs 121 |

59 | - -- * 'genRange' always returns a pair of defined 'Int's. |

60 | + -- * 'genRange' always returns a pair of defined values. |

61 | -- |

62 | -- The second condition ensures that 'genRange' cannot examine its |

63 | -- argument, and hence the value it returns can be determined only by the |

64 | hunk ./System/Random.hs 129 |

65 | -- a single call to 'genRange' to establish a generator's range, without |

66 | -- being concerned that the generator returned by (say) 'next' might have |

67 | -- a different range to the generator passed to 'next'. |

68 | - -- |

69 | - -- The default definition spans the full range of 'Int'. |

70 | - genRange :: g -> (Int,Int) |

71 | - |

72 | - -- default method |

73 | - genRange _ = (minBound, maxBound) |

74 | + genRange :: g -> (v,v) |

75 | |

76 | -- | The class 'SplittableGen' proivides a way to specify a random number |

77 | -- generator that can be split into two new generators. |

78 | hunk ./System/Random.hs 171 |

79 | data StdGen |

80 | = StdGen Int32 Int32 |

81 | |

82 | -instance RandomGen StdGen where |

83 | +instance RandomGen StdGen Int where |

84 | next = stdNext |

85 | genRange _ = stdRange |

86 | |

87 | hunk ./System/Random.hs 227 |

88 | -- FIXME: 1/2/3 below should be ** (vs@30082002) XXX |

89 | |

90 | {- | |

91 | -With a source of random number supply in hand, the 'Random' class allows the |

92 | -programmer to extract random values of a variety of types. |

93 | +With a source of random values (of type v) supply in hand, the 'Random' class allows the |

94 | +programmer to coerce the v values into values of type a. |

95 | |

96 | Minimal complete definition: 'randomR' and 'random'. |

97 | |

98 | hunk ./System/Random.hs 234 |

99 | -} |

100 | |

101 | -class Random a where |

102 | +class Random a v where |

103 | -- | Takes a range /(lo,hi)/ and a random number generator |

104 | -- /g/, and returns a random value uniformly distributed in the closed |

105 | -- interval /[lo,hi]/, together with a new generator. It is unspecified |

106 | hunk ./System/Random.hs 241 |

107 | -- what happens if /lo>hi/. For continuous types there is no requirement |

108 | -- that the values /lo/ and /hi/ are ever produced, but they may be, |

109 | -- depending on the implementation and the interval. |

110 | - randomR :: RandomGen g => (a,a) -> g -> (a,g) |

111 | + randomR :: RandomGen g v => (a,a) -> g -> (a,g) |

112 | |

113 | -- | The same as 'randomR', but using a default range determined by the type: |

114 | -- |

115 | hunk ./System/Random.hs 252 |

116 | -- @[0,1)@. |

117 | -- |

118 | -- * For 'Integer', the range is (arbitrarily) the range of 'Int'. |

119 | - random :: RandomGen g => g -> (a, g) |

120 | + random :: RandomGen g v => g -> (a, g) |

121 | |

122 | -- | Plural variant of 'randomR', producing an infinite list of |

123 | -- random values instead of returning a new generator. |

124 | hunk ./System/Random.hs 256 |

125 | - randomRs :: RandomGen g => (a,a) -> g -> [a] |

126 | + randomRs :: RandomGen g v => (a,a) -> g -> [a] |

127 | randomRs ival g = x : randomRs ival g' where (x,g') = randomR ival g |

128 | |

129 | -- | Plural variant of 'random', producing an infinite list of |

130 | hunk ./System/Random.hs 261 |

131 | -- random values instead of returning a new generator. |

132 | - randoms :: RandomGen g => g -> [a] |

133 | + randoms :: RandomGen g v => g -> [a] |

134 | randoms g = (\(x,g') -> x : randoms g') (random g) |

135 | |

136 | hunk ./System/Random.hs 264 |

137 | - -- | A variant of 'randomR' that uses the global random number generator |

138 | - -- (see "System.Random#globalrng"). |

139 | - randomRIO :: (a,a) -> IO a |

140 | - randomRIO range = getStdRandom (randomR range) |

141 | +-- | A variant of 'randomR' that uses the global random number generator |

142 | +-- (see "System.Random#globalrng"). |

143 | +randomRIO :: (Random a Int) => (a,a) -> IO a |

144 | +randomRIO range = getStdRandom (randomR range) |

145 | |

146 | hunk ./System/Random.hs 269 |

147 | - -- | A variant of 'random' that uses the global random number generator |

148 | - -- (see "System.Random#globalrng"). |

149 | - randomIO :: IO a |

150 | - randomIO = getStdRandom random |

151 | +-- | A variant of 'random' that uses the global random number generator |

152 | +-- (see "System.Random#globalrng"). |

153 | +randomIO :: (Random a Int) => IO a |

154 | +randomIO = getStdRandom random |

155 | |

156 | |

157 | hunk ./System/Random.hs 275 |

158 | -instance Random Int where |

159 | +instance Random Int Int where |

160 | randomR (a,b) g = randomIvalInteger (toInteger a, toInteger b) g |

161 | random g = randomR (minBound,maxBound) g |

162 | |

163 | hunk ./System/Random.hs 279 |

164 | -instance Random Char where |

165 | +instance Random Char Int where |

166 | randomR (a,b) g = |

167 | case (randomIvalInteger (toInteger (ord a), toInteger (ord b)) g) of |

168 | (x,g') -> (chr x, g') |

169 | hunk ./System/Random.hs 285 |

170 | random g = randomR (minBound,maxBound) g |

171 | |

172 | -instance Random Bool where |

173 | +instance Random Bool Int where |

174 | randomR (a,b) g = |

175 | case (randomIvalInteger (bool2Int a, bool2Int b) g) of |

176 | (x, g') -> (int2Bool x, g') |

177 | hunk ./System/Random.hs 300 |

178 | |

179 | random g = randomR (minBound,maxBound) g |

180 | |

181 | -instance Random Integer where |

182 | +instance Random Integer Int where |

183 | randomR ival g = randomIvalInteger ival g |

184 | random g = randomR (toInteger (minBound::Int), toInteger (maxBound::Int)) g |

185 | |

186 | hunk ./System/Random.hs 304 |

187 | -instance Random Double where |

188 | +instance Random Double Int where |

189 | randomR ival g = randomIvalDouble ival id g |

190 | random g = randomR (0::Double,1) g |

191 | |

192 | hunk ./System/Random.hs 309 |

193 | -- hah, so you thought you were saving cycles by using Float? |

194 | -instance Random Float where |

195 | +instance Random Float Int where |

196 | random g = randomIvalDouble (0::Double,1) realToFrac g |

197 | randomR (a,b) g = randomIvalDouble (realToFrac a, realToFrac b) realToFrac g |

198 | |

199 | hunk ./System/Random.hs 319 |

200 | (sec, psec) <- getTime |

201 | return (createStdGen (sec * 12345 + psec + ct + o)) |

202 | |

203 | -randomIvalInteger :: (RandomGen g, Num a) => (Integer, Integer) -> g -> (a, g) |

204 | +randomIvalInteger :: (RandomGen g Int, Num a) => (Integer, Integer) -> g -> (a, g) |

205 | randomIvalInteger (l,h) rng |

206 | | l > h = randomIvalInteger (h,l) rng |

207 | | otherwise = case (f n 1 rng) of (v, rng') -> (fromInteger (l + v `mod` k), rng') |

208 | hunk ./System/Random.hs 335 |

209 | in |

210 | f (n' - 1) (fromIntegral x + acc * b) g' |

211 | |

212 | -randomIvalDouble :: (RandomGen g, Fractional a) => (Double, Double) -> (Double -> a) -> g -> (a, g) |

213 | +randomIvalDouble :: (RandomGen g Int, Fractional a) => (Double, Double) -> (Double -> a) -> g -> (a, g) |

214 | randomIvalDouble (l,h) fromDouble rng |

215 | | l > h = randomIvalDouble (h,l) fromDouble rng |

216 | | otherwise = |

217 | } |

218 | |

219 | Context: |

220 | |

221 | [Move "split" into its own class |

222 | thomas.dubuisson@gmail.com**20100914232945 |

223 | Ignore-this: 588e2a321823c206962b77c12cdb652a |

224 | ] |

225 | [Fix randomIvalDouble so that it will not produce values more than a few ULPs below the requested lower bound |

226 | James Cook <james.cook@usma.edu>**20100412132638 |

227 | Ignore-this: 35a65dae123bbf5f812ebd0aac7aa3b1 |

228 | ] |

229 | [Bump version to 1.0.0.2 |

230 | Ian Lynagh <igloo@earth.li>**20090920141953] |

231 | [use explicit import list for Data.Sequence, in preparation for an expanded interface |

232 | Ross Paterson <ross@soi.city.ac.uk>**20090913230910 |

233 | Ignore-this: d6f37ea56cff7c7f4edcafb89b2a9f |

234 | ] |

235 | [Fix "Cabal check" warnings |

236 | Ian Lynagh <igloo@earth.li>**20090811215920] |

237 | [change dependency from old-time to time |

238 | Laszlo Nagy <rizsotto@gmail.com>**20090709091417 |

239 | Ignore-this: de203b243bd2f4035661c91971bd49cc |

240 | ] |

241 | [TAG 2009-06-25 |

242 | Ian Lynagh <igloo@earth.li>**20090625160406] |

243 | Patch bundle hash: |

244 | fe3fd8c03e81aaf4e9a7d98e3911905619ecd598 |