[Haskell-cafe] Re: Haskell stacktrace

wren ng thornton wren at freegeek.org
Wed Sep 10 01:37:08 EDT 2008


Pieter Laeremans wrote:
> This :
> Prelude> let f = (\x -> return "something went wrong")  ::   IOError -> IO
> String
> Prelude> let t = return $ show $ "too short list" !! 100 :: IO String
> Prelude> catch t f
> "*** Exception: Prelude.(!!): index too large
> 
> doesn't work.


As others've said, the right answer is to correct the bug rather than 
doing exception handling, but in as far as knowing how to do exception 
handling for "pure" functions, consider:

   http://code.haskell.org/~wren/wren-extras/Control/Exception/Extras.hs

The trickiest thing to watch out for is that you must strictly evaluate 
the expression or else the return/evaluate function will just lazily 
thunk up the expression. Which means that when you finally run the IO, 
you'll have already stripped off the IO wrapper that can catch the 
exception prior to evaluating the expression (which then throws an 
exception out past the catcher).

Another thing to watch out for is that Prelude.catch doesn't do what you 
want because the H98 spec declares these exceptions to be uncatchable. 
The Control.Exception.catch function does what you want and is portable 
even though it's not H98.

If you're doing the unsafePerformIO trick to purify your exception 
handling be sure to give a NOINLINE pragma to prevent potentially buggy 
inlining. You should also be sure that the handler is something which is 
actually safe to unsafePerformIO.

Finally, to ensure that other optimizations or evaluation orders don't 
accidentally mess you up, you should take the higher-order approach of 
`safely` to ensure that you don't accidentally apply the function prior 
to wrapping it up in a catcher.

-- 
Live well,
~wren


More information about the Haskell-Cafe mailing list