Fwd: Re: [Haskell-cafe] [Newbie question] -- Looping stdin until condition is met

FYI.
On Sat, 31 May 2008 02:11:13 +0200, "Daniel Fischer"
Am Samstag, 31. Mai 2008 02:28 schrieb Martin 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). I have tried tons of variants and modifications of code, and I can't find the way to implement this. Here is what my emacs buffer is at now::
import Text.Read import System.IO import qualified Control.Exception as C
getNum :: IO Int getNum = do line <- (hGetLine stdin) x <- (C.catch (do return (read line :: Int)) (\e -> getNum)) return x
All you need is a little strictness, x <- (C.catch (return $! read line :: Int) (\e -> getNum)) works. Another option is using evaluate instead of return. The problem is that (read line :: Int) is not evaluated until it is needed, that is when it's going to be printed, but then it's too late to catch the exception.
Some general remarks: hGetLine stdin === getLine do x <- action return x is the same as action
main = do x <- getNum putStr ((show x) ++ "\n")
print x
Now, I've tried the Prelude's catch, the Control.Exception catch, I've tried moving it at the top of getnum, I've tried without catch, I've tried a ton of other shtuff, so much that I'm starting to think that Emacs is going to run out of electrons soon. I asked some half-newbie friends who are insanely enthousiastic about Haskell and they can't do it either (I'm starting to think that those enthousiastic friends are dating a beautiful girl with 3 PhDs, but she has a 2-inch thick green and gooey wart smack on her nose and they're so blindly in love that they can't admit that she does). I've asked some university profs and they sidetrack my question by saying I shouldn't do I/O so early. Can anyone here restore my faith in the Haskell section of humanity?
1. How do I catch the exception that is raised from "read"?
By forcing the evaluation.
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.)
Get used to lazy evaluation, the Hutton book should contain a chapter about that.
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.
Thanks in advance.
participants (1)
-
Martin Blais