I want to generate a list with random numbers in Haskell. I have to use the import System.Random library. I started doing something like that but it doesn't work. I have to create a list with N positions, and all these positions must have random numbers. Thanks!
System.Random library
import System.IO
x = randomRIO (1,6::Int)
test :: IO Int
test = randomRIO (1,6::Int)
You need to run randomRIO
n times. For this you can use replicate
. This will give you a list of monadic values, that you can transform into a monadic list of values with sequence
:
test :: Int -> IO [Int]
test n = sequence $ replicate n $ randomRIO (1,6::Int)
While JP Moresmau solution is certainly preferable, you might be interested in a more transparent solution that shines some light on the do
notation and recursive functions using IO
:
import System.Random (randomRIO)
randomList :: Int -> IO([Int])
randomList 0 = return []
randomList n = do
r <- randomRIO (1,6)
rs <- randomList (n-1)
return (r:rs)
you should note the following:
n == 0
the function will use return
to wrap the empty list into IO
and return thisdo
body it will first generate a random number r
using randomRIO
n-1
element list of random numbers using randomList (n-1)
and bind it to rs
return
again to wrap r:rs
(a n
element list) into IO
and return ithere is an example in GHCi:
λ> randomList 10
[2,4,4,5,2,2,2,5,6,2]
λ> randomList 10
[2,4,4,2,5,2,6,3,4,1]
seems random enough
the function has a problem with certain values of n
- can you spot it? And if so - can you change the function to be total?
If you look closely you see that you can pull out randomRIO (1,6) :: IO Int
there like this:
mList :: Int -> IO a -> IO([a])
mList 0 gen = return []
mList n gen = do
r <- gen
rs <- mList(n-1) gen
return (r:rs)
which of course you would have to use like this:
λ> mList 10 $ randomRIO (1,6)
[2,2,2,5,5,1,3,6,6,1]
now this has been done before (in a slightly different/better) way and you can find it as replicateM
in Control.Monad
- with this import the function simplifies to:
import System.Random (randomRIO)
import Control.Monad (replicateM)
randomList :: Int -> IO([Int])
randomList n = replicateM n $ randomRIO (1,6)
fun fact internally this is implemented exactly as what JP answered ;)
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