Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: random number - Int of IO action

I recently picked up Haskell and the syntax is really confusing to me. I am trying to get a random number between 0 and 51 using:

randomRIO (0, 51)

But I don't know how to make this an actual Int (instead of IO Int).

I believe you are supposed to be able to do:

gen <- randomRIO (0, 51)

and then gen is supposed to be an Int, but I have to do this in a do-block - how do I create the function that takes this and returns an Int?

From googling I'm afraid that there is something basic that I do not understand. I am completely lost.

like image 850
Meltdown Avatar asked Dec 02 '22 11:12

Meltdown


1 Answers

Yep, there is something basic, and it's the most common thing new Haskellers struggle with. Basically, everything you said is right, and if you want a "function" that returns a random int, you can't have it.

You can do

main :: IO ()
main = do
    num <- getRandomR (0, 51)
    putStrLn ("The number is " ++ show num)

You can also factor it out

getCardIndex :: IO Int
getCardIndex = do
    ix <- getRandomR (0,51)
    return (ix + 1)   -- just as an example of how you can transform it

main :: IO ()
main = do
    card <- getCardIndex
    putStrLn ("The number is " ++ show card)

The thing you can't do is make it a pure function/value:

pureCardIndex :: Int
pureCardIndex = ioToPure (getRandomR (0,51)) -- NOT POSSIBLE

because there is no (ethical) function like ioToPure. A pure function must always return the same output for the same input, which is precisely not what you want a random number function to do. So we have to use IO with it. Once you use IO to generate something random, anything that depends on that random number must also be in IO.

People will be quick to start explaining the theory of monads and all that, and it's good stuff, I just recommend approaching it patiently, getting used to these patterns before diving into the theoretical side.

like image 163
luqui Avatar answered Dec 14 '22 23:12

luqui