Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate an infinite list of random numbers using randomRIO?

Tags:

haskell

I'm trying to generate an infinite list of random numbers using randomRIO.

import System.Random

g :: IO [Integer]
g = do
  n <- randomRIO (1,6) :: IO Integer
  f <- g
  return (n : f)

It compiles but hangs when run.

like image 834

2 Answers

The problem with your code is that it never teminates. Whenever you execute g, it initially calcuates the first random number and stores it in n. Then it again recursively calls back to the same function g which goes on and on. To get an infinite list you can use the randomRs function:

g2 :: IO [Integer]
g2 = do
  g <- newStdGen
  return $ randomRs (1,6) g

And then you can produce any number of random numbers using it:

λ> g2 >>= \x -> return $ take 5 $ x
[5,4,6,5,6]
like image 176
Sibi Avatar answered Apr 20 '23 01:04

Sibi


Well, you can't, for much the same reason why you can't lazily mapM over State (and then use the result state afterwards). randomRIO produces a single value and only hands on the monadic program flow after this value has been produced.

The way to produce infinite streams of random values is of course randomRs. You can easily couple it with getStdRandom to produce such streams right in IO:

import Control.Arrow

randomRsIO :: Random a => (a,a) -> IO [a]
randomRsIO range = getStdRandom $ split >>> first (randomRs range)

With that,

g :: IO [Integer]
g = randomRsIO (1,6)
like image 27
leftaroundabout Avatar answered Apr 20 '23 01:04

leftaroundabout