# [Haskell-cafe] "safe" way to use Rand?

Michael Mossey mpm at alumni.caltech.edu
Mon Oct 12 09:23:03 EDT 2009

```I'm looking at Control.Monad.Random which provides the Rand monad. I would
like to know how to use this for generating multiple infinite series, while
trusting that the implementation never uses "split" behind the scenes.

(Note: I'm on Windows XP, and there appears to be a bug in getStdGen. It
does NOT return an arbitrary generator, but rather the same one every time
I run the program. However, newStdGen DOES return an arbitrary generator.
So I'm using that, even though I know it accesses split behind the scenes.
My thinking is that this only happens once so it is okay.)

For example, is this code split-free?

simple :: Rand StdGen [Int]
simple = getRandomRs (0::Int, 10)

main1 = do
gen <- newStdGen
let answer = (flip evalRand) gen \$ do
xs <- simple
ys <- simple
return \$ (take 5 xs) ++ (take 3 ys)

Then, to elaborate on my specific problem, I need to create special types
of infinite series. For example, I might need to create one that looks like
this:

0 0 5 0 0 0 2 0 0 0 0 0 5 0 9 0 0 8 ...

The pattern here is that there is some random number of zeros followed by a
single non-zero value, followed again by a random number of zeros, etc.
forever.

This is one way to implement this. Does all look well here?

makeSeries :: [Int] -> [a] -> a -> [a]
makeSeries (i:is) (f:fs) zero = replicate i zero ++ [f]
++ makeSeries is fs zero

lessSimple :: Rand StdGen [Int]
lessSimple = do
counts <- getRandomRs (1::Int  , 5  )
values <- getRandomRs (1::Int  , 9  )
return \$ makeSeries counts values 0

main2 = do
gen <- newStdGen
let answer = evalRand lessSimple gen
print . take 20 \$ answer

We could even have several of these series zipped together. Is this split-free?

main3 = do
gen <- newStdGen
let fs = (flip evalRand) gen \$ do
s1 <- lessSimple
s2 <- lessSimple
return \$ zip s1 s2
print . take 20 \$ fs

```