
blais:
Allright, this is a definitely a newbie question.
I'm learning Haskell and going through the exercises in the beautiful Hutton book, and one of them requires for me to write a loop that queries a line from the user (stdin), looping until the user enters a valid integer (at least that's how I want to implement the interface to the exercise).
1. How do I catch the exception that is raised from "read"?
The best thing to do is bypass read and use 'reads' to define your own safe read. maybeRead :: Read a => String -> Maybe a maybeRead s = case reads s of [(x, "")] -> Just x _ -> Nothing For example, yielding: import System.IO main = do x <- getNum print x getNum :: IO Integer getNum = do n <- getLine case maybeRead n of Nothing -> getNum Just n -> return n
2. Where do I find the appropriate information I need in order to fix this? I'm probably just not searching in the right place. (Yes, I've seen the GHC docs, and it doesn't help, maybe I'm missing some background info.)
I think Control.Exception.catch should be fine here.
3. Please do not tell me I should solve the problem differently. Here is the problem I'm trying to solve, and nothing else:
"Write a program that reads a line from the user, looping the query until the line contains a valid integer."
It shouldn't be too hard i think. The best answer would be a two-liner code example that'll make me feel even more stupid than I already do.
Of course, it's easy. You can have fun now abstracting out the loop form in getNum using say, MaybeT or friends. But a loop is simple and easy. If you want to write it with explict exception handling of the read parse failure, it's more tedious, as you need to ensure the read exception is thrown within the body of the enclosing catch. For example, import System.IO import qualified Control.Exception as C main = do x <- getNum print x getNum :: IO Integer getNum = do y <- maybeRead case y of Nothing -> getNum Just n -> return n maybeRead :: Read a => IO (Maybe a) maybeRead = C.catch (do x <- getLine let n = read x n `seq` return (Just n)) -- ensure any exception is thrown here (const (return Nothing)) -- Don