
On Mon, Nov 30, 2009 at 8:36 PM, Hector Guilarte
One time I needed to do use a random number in some places of a completly pure program so I made a infinite list of random numbers and passed it around all the time in the functions as they where called, using the head of the list I passed to the function whenever I needed a random number and returning a tuple which it's second element was the tail of the random numbers list e.g.
f:: [int] -> (a,[Int]) f randomList = let usedRandomNumber = g $ head randomList in (usedRandomNumber,(tail randomList))
or even something like: f:: [int] -> (a,[Int]) f randomList = let (usedRandomNumber,newRandomList) = g randomList in (usedRandomNumber,newRandomList)
This pattern can be encapsulated in a monad: newtype RandM a = RandM { unRandM :: [Int] -> (a,[Int]) } instance Monad RandM where return x = RandM $ \randomList -> (x, randomList) m >>= g = RandM $ \randomList -> let (x, newRandomList) = unRandM m randomList in unRandM (g x) newRandomList getRandom :: RandM Int getRandom = RandM $ \(randomNumber:randomList) -> (randomNumber, randomList) See the similarity? Of course, there is no need to implement this yourself. It is already implemented as State [Int]. And as long as you are doing that, you might as well use Rand from the MonadRandom package. In fact, I have argued that you should use MonadRandom instead of the lower-level System.Random whenever possible: http://lukepalmer.wordpress.com/2009/01/17/use-monadrandom/ Luke