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


