The objective is to code the game of Nim in Haskell as a school assignment. I'm new to Haskell and get weird behavior when I try to read input.
The goal is to read two integers. Instead of printing the first message, then prompting and then going on to the second one, it just prints the two messages and I'm unable to give proper input. What is wrong here?
type Board = [Int] -- The board
type Heap = Int -- id of heap
type Turn = (Int, Int) -- heap and number of stars to remove
readInt :: String -> IO Int
readInt msg = do putStr (msg ++ "> ")
inp <- getChar
let x = ord inp
return x
readTurn :: Board -> IO(Turn)
readTurn b = do heap <- readInt "Select heap:"
amt <- readInt "Select stars:"
print heap
print amt
return(heap, amt)
The problem is that stdout
is line-buffered by default, which means that nothing gets output until you print a newline. There are two ways to solve this:
hFlush stdout
after printing the prompt to flush the buffer.hSetBuffering stdout NoBuffering
at the start of your program to disable output buffering.Also, using getChar
and ord
will read a single character and give you its ASCII value, which is probably not what you wanted. To read and parse a number, use readLn
:
import System.IO (hFlush, stdout)
readInt :: String -> IO Int
readInt msg = do
putStr (msg ++ "> ")
hFlush stdout
readLn
readChar
reads only one character at a time. I assume you want instead to read a whole line, convert it to a number (possibly with more than one digit), and continue. You need to use getLine :: IO String
and read :: Read a => String -> a
:
readInt :: String -> IO Int
readInt msg = do
putStr (msg ++ "> ")
hFlush stdout
inp <- getLine
return (read inp)
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