Reputation: 893
I'm trying to write a program that loops all the time waiting for an input from the user but for some reason it doesn't loop. My program is :
charAt :: String->Char->Int
main = do
x <- readLn
if x == 1
then do
putStrLn "Word: "
word <- getLine
putStrLn "Char: "
ch <- getChar
putStrLn (show (charAt word ch))
else print "Nothing"
main
But i actually get this error:
*** Exception: user error (Prelude.readIO: no parse)
If i remove the last main calling the program will work . does anybody knows why is that happening?
Upvotes: 1
Views: 3446
Reputation: 105876
When you use getChar
, it will take only a single character from your stream. However, if you've entered AEnter, the newline character '\n'
is still in your stdin
. A '\n'
cannot get parsed into an Int
, therefore you end up with that error.
You can remove that newline if you call getLine
afterwards:
ch <- getChar
putStrLn (show (charAt word ch))
_ <- getLine
Or you write your own helpers:
promptInt :: IO Int
promptInt = do
putStr "Int: "
line <- getLine
case readMaybe line of
Just x -> return x
_ -> putStrLn "Try again." >> promptInt
promptChar :: IO Char
promptChar = do
putStr "Char: "
line <- getLine
case line of
[x,_] -> return x
_ -> putStrLn "Try again." >> promptChar
Upvotes: 4