I wrote a function to generate two random numbers, which I then pass to a different function to use them there. The code for this is:
randomIntInRange :: (Int, Int, Int, Int) -> Board
randomIntInRange (min,max,min2,max2) = do r <- randomRIO (min, max)
r2 <- randomRIO (min2, max2)
randomCherryPosition (r, r2)
And the function this function calls in its 'do' block is:
randomCherryPosition :: (Int, Int) -> Board
randomCherryPosition (x, y) = initialBoard & element y . element x .~ C
Where initialBoard
is a list of lists and C is a predefined data type. I am using lens
to change values inside the list. Running this gives me the error:
Couldn't match type ‘IO’ with ‘[]’
Expected type: [Int]
Actual type: IO Int
for both r and r2 lines. I have absolutely no idea what is going on here, or what i'm doing wrong, so I would greatly appreciate any help.
randomRIO
has type IO Int
, not Int
. As long as you use any IO
functions, your surrounding function must also be in IO
:
randomIntInRange :: (Int, Int, Int, Int) -> IO Board
randomIntInRange (min,max,min2,max2) = do r <- randomRIO (min, max)
r2 <- randomRIO (min2, max2)
pure $ randomCherryPosition (r, r2)
randomRIO
is not a pure function. It returns a different value every time. Haskell bans such functions. There are numerous benefits that come from banning such functions, which I'm going to go into here. But you can still have such function if you wrap it in IO
. The type IO Int
means "it's a program that, when executed, will produce an Int
". So when you call randomRIO (min, max)
, it returns you not an Int
, but a program, which you can then execute to get an Int
. You do the execution via the do
notation with left arrow, but the result of that would also be a similar program.