Niko Zarzani
Niko Zarzani

Reputation: 1402

Why catch is not working?

I am trying to read an Int from the input and managing a bad input from the user.

This a piece of code that does the job but it seems it is not working...

asknumplayers = do {
putStr "Please the number of other players:\n";
numstr <- getLine;
maybenum <- catch  (return (Just (read numstr::Int))) (\(e::SomeException) -> return Nothing);
case maybenum of
    Nothing -> asknumplayers;
    Just num -> return num; 
}

And this is the main:

main = do {
num <- asknumplayers;
putStr $ "Thank you, ready to play against "++ (show num) ++" players?!\n";
}

The problem is that the I still get "* Exception: Prelude.read: no parse" when the string is printed in the main. Is it a problem of lazy evaluation? How should I solve it?

Upvotes: 1

Views: 145

Answers (1)

Joachim Breitner
Joachim Breitner

Reputation: 25762

Yes, it is caused by lazy evaluation. The code return (Just (read numstring)) will not cause the read to happen, that will only happen in main when putStr evaluates (forces) the string.

Do not use exceptions for that, but rather a more suitable function like readMaybe from Text.Read, or one of the functions from the Safe module in the safe package.

Upvotes: 6

Related Questions