| 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 |
|---|