Printruler

Asking the user for confirmation

2024.01.18 19:05 your_pasty_butt Asking the user for confirmation

Hello! I am currently learning Haskell. I found an online book Learn You A Haskell For Great Good! which I am using.

I started writing a number guessing game as an excercise. The game should proceed as follows:
- Generate a random number 1..15
- Ask the user for a number 1..15
- If the numbers match, congratulate the user, otherwise ask if they wish to continue
- If the user wants to continue, go to step 1
- Otherwise, exit.

I am having problems with the function that asks the user if they want to continue. I have boiled my problem down one half-solution:
userWantsToContinue :: IO Bool userWantsToContinue = do putStr "Do you want to try again? [Y/N] " opt <- getLine let isYes = opt `elem` ["Y", "y"] let isNo = not isYes && (opt `elem` ["N", "n"]) if not (isYes isNo) then userWantsToContinue else isYes 
This obviously errors out on the else isYes part since isYes is a Bool rather than an IO Bool.
My question is, how should I implement this function? I'm aware I can use return to convert a Bool into an IO Bool but I have also understood that's a stupid idea.
Here's the entire code, I'm very very new to Haskell (started yesterday) so I could certainly use feedback.
module Main where import Control.Monad import Data.Char (isDigit) import GHC.IO.Handle (BufferMode (NoBuffering), hSetBuffering) import GHC.IO.Handle.FD (stdout) import System.Random (randomRIO) main :: IO () main = do -- Prevent printing things in the wrong order hSetBuffering stdout NoBuffering playGame -- Runs the game logic. playGame :: IO () playGame = do printRules -- Make a random number, and ask the user for their guess. answer <- getRandomNum 1 15 asked <- askNumber 1 15 if answer == asked then putStrLn "Correct!" else putStrLn "The answer was not correct." continue <- userWantsToContinue when continue playGame -- Asks the user if they want to continue playing the game. userWantsToContinue :: IO Bool userWantsToContinue = do putStr "Do you want to try again? [Y/N] " opt <- getLine let isYes = opt `elem` ["Y", "y"] let isNo = not isYes && (opt `elem` ["N", "n"]) if not (isYes isNo) then userWantsToContinue else isYes -- Checks if the given string is a number composed of the characters 0-9. isNumber :: String -> Bool isNumber = all isDigit -- Prints the rules of the game. printRules :: IO () printRules = putStrLn "This is a number guessing game. You have to guess a number between 1 and 15." -- Asks for a number in a given range. -- If the format of the number is invalid or the number is not in the given range the number is asked again, -- until a valid number is entered. askNumber :: Int -> Int -> IO Int askNumber lower upper = do putStr "Enter a number from 1 to 15: " num <- getLine if isNumber num then do let parsed = readIO num :: IO Int parsedInt <- parsed if parsedInt > upper parsedInt < lower then askNumber lower upper else parsed else askNumber lower upper getRandomNum :: Int -> Int -> IO Int getRandomNum lower upper = randomRIO (lower, upper) :: IO Int 
Thank you for helping!
submitted by your_pasty_butt to haskell [link] [comments]


http://rodzice.org/