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.
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]
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With