If statement using IO Int haskell

  • A+
Category:Languages

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 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: