Haskell: The Craft of Functional Programming Simon Thompson (c) Addison-Wesley, 1999. Random number generation. Lazy programming ^^^^^^^^^^^^^^^^ > module RandomGen where Find the next (pseudo-)random number in the sequence. > nextRand :: Int -> Int > nextRand n = (multiplier*n + increment) `mod` modulus A (pseudo-)random sequence is given by iterating this function, > randomSequence :: Int -> [Int] > randomSequence = iterate nextRand Suitable values for the constants. > seed, multiplier, increment, modulus :: Int > seed = 17489 > multiplier = 25173 > increment = 13849 > modulus = 65536 Scaling the numbers to come in the (integer) range a to b (inclusive). > scaleSequence :: Int -> Int -> [Int] -> [Int] > scaleSequence s t > = map scale > where > scale n = n `div` denom + s > range = t-s+1 > denom = modulus `div` range Turn a distribution into a function. > makeFunction :: [(a,Double)] -> (Double -> a) > makeFunction dist = makeFun dist 0.0 > makeFun ((ob,p):dist) nLast rand > | nNext >= rand && rand > nLast > = ob > | otherwise > = makeFun dist nNext rand > where > nNext = p*fromInt modulus + nLast Random numbers from 1 to 6 according to the example distribution, dist. > randomTimes :: [Int] > randomTimes = map (makeFunction dist . fromInt) (randomSequence seed) The distribution in question > dist :: [(Int,Double)] > dist = [(1,0.2), (2,0.25), (3,0.25), (4,0.15), (5,0.1), (6,0.05)]