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

Ryan Ingram ryani.spam at gmail.com
Mon Jun 2 18:52:29 EDT 2008


On 5/30/08, Martin Blais <blais at furius.ca> wrote:
> Dear Philip, could you point your virtual finger towards a
> reference/paper/book/any-bleeping-thing that would help this simple
> beginner understand why it doesn't work in this case? I'm trying to
> picture why a "read" function that terminates the program would be
> useful anywhere. In fact, any library function other than something like
> UNIX's "exit" or "kill" which terminates my program is not really
> welcome in any of my computer programs, but then again, I haven't yet
> been illuminated by the genie of pure functional languages.  A reference
> would be awesome.

As others have pointed out, the reason why it doesn't work is due to
lazy evaluation; the exception is "hidden" in a pure value and isn't
triggered until some other bit of code causes the pure value to be
evaluated.  You can force the exception to be generated in your catch
block by using "seq" (or "$!", which is implemented using "seq").
This forces the evaluation to happen at that point, although there are
a lot of gotchas involved; for Int it works fine, though.

Your question, then, requires asking "why would you want to hide an
exception in a pure value"?  The answer to that is quite interesting,
but here's a simpler example that might enlighten you:

head :: [a] -> a
head (x:_) = x
head _ = error "head: empty list"

Just as you are required to prove before calling "head" that you
aren't passing an empty list, for your program to be total, you should
prove before calling "read" that the string parses properly.  If you
can't provide that proof (because, in this case, the string is
provided by the user), you should be using another function for
parsing.

Don suggested "reads" to implement "maybeRead", which seems like a
great idea to me.

  -- ryan


More information about the Haskell-Cafe mailing list