I have a game , user vs computer and I want to randomly choose who starts the game. I have
a = getStdRandom $ randomR (0, 1)
This gets a random number 0 or 1. However it is a IO Int, so I can't have an if statement comparing it to a number like
if a == 0 then userStarts else computerStarts
I have tried to compare IO Int with IO Int and it doesn't work, and I have also tried
Converting IO Int to Int
I am very new to Haskell, not sure how to approach this. Code details requested:
randomNumber = getStdRandom $ randomR (0, length symbols - 5) -- this will be 0 or 1
randomNumber2 = getStdRandom $ randomR (0, length symbols - 5) -- according to
-- the solution I need another function returning IO int.
a = do
x <- randomNumber
randomNumber2 $ pureFunction x
Error I get:
• Couldn't match expected type ‘t0 -> IO b
with actual type ‘IO Int’
• The first argument of ($) takes one argument,
but its type ‘IO Int’ has none
In a stmt of a 'do' block: randomNumber2 $ pureFunction x
In the expression:
do x <- randomNumber
randomNumber2 $ pureFunction x
• Relevant bindings include
a :: IO b
(bound at Path:87:1)
randomNumber2 $ pureFunction x
Path:89:20: error:
Variable not in scope: pureFunction :: Int -> t0
randomNumber2 $ pureFunction x
When you say a = getStdRandom $ randomR (0,1) you are saying "let a be the action of getting a random value between 0 and 1". What you want is within some function's do block a <- getStdRandom $ randomR (0,1) which is "let a be the result of running the action of getting a random value between 0 and 1".
As such:
import System.Random
main :: IO ()
main = do
a <- getStdRandom $ randomR (0, 1 :: Int)
if a == 0 then userStarts else computerStarts
-- Placeholders for completeness
userStarts, computerStarts :: IO ()
userStarts = putStrLn "user"
computerStarts = putStrLn "computer"
N.B. I specified the 1 is an int or else the compiler won't know if you want a random int, int64, double, float, or something else entirely.
EDIT: @monocell makes a good point that generating an int in a range just to get a boolean is somewhat indirect. You can just directly generate a boolean result and this requires no range:
a <- getStdRandom random
if a then userStarts else computerStarts
Not sure how your code looks like, but have you tried doing what the linked resource recommends (using the do block)?
do
(result, newGenerator) <- randomR (0, 1) generator
-- ...
That will get you access to result, which is of the same type as 0 and 1.
Can you show your code/the error you get?
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