Reputation: 179
I'm new to haskell and I've been trying to figure out this problem for a while now. I want to generate a list of a random size using randomRIO and have that list be populated with random numbers using randomIO. I have tried to approach this problem by creating a function which takes in the randomly generated from randomRIO like so:
x <- randomRIO(1,5)
let y = randList x []
the function itself is something like this:
randList :: Int -> IO [Int] -> IO [Int]
randList 0 xs = return [xs]
randList g xs = do
t <- randomIO
let a = t:randList (g-1) xs
return [a]
I'm not sure how to handle the monad IO in a recursive function but this is how I'm thinking of it. Any help is appreciated thanks!
Upvotes: 0
Views: 191
Reputation: 94299
You can use replicateM
to repeatedly execute randomIO
, generating a new number each time. You call randomRIO
once up front to decide on the length of the list:
import Control.Monad (replicateM)
import System.Random (randomIO, randomRIO)
randList :: IO [Int]
randList = do
len <- randomRIO (1,5)
replicateM len randomIO
Now, your definition wasn't actually very far off. A couple of things though:
Given that you expect to be able to call randList x []
, the second argument of randList
clearly is a plain list. Not an IO action of some sort. So your type should be
randList :: Int -> [Int] -> IO [Int]
In your first pattern match
randList 0 xs = return [xs]
Remember that xs
is already a list. So when you do return [xs]
you will get an IO [[Int]]
, a list of lists. What you want here is a plain return xs
.
In your second definition
randList g xs = do
t <- randomIO
let a = t:randList (g-1) xs
return [a]
The expression t:randList ...
makes no sense. The right-hand side of :
must be a list. randList
does not yield a list though, it yields an IO action. What you actually want to do is to treat the second argument of randList
(the list) as an "accumulator", which is gradually built up. So you want to generate a number, add it to the accumulator, and then recurse with g
decreased by one:
randList g xs = do
t <- randomIO
randList (g-1) (t:xs)
Upvotes: 4