
ChrisK
You should ensure that the result of "evaluate" is in normal form, not just weak head normal form. You can do this with the Control.Parallel.Strategies module:
import Control.Exception(ArithException(..),try,evaluate) import Control.Parallel.Strategies(NFData,using,rnf) import System.IO.Unsafe(unsafePerformIO)
tryArith :: NFData a => a -> Either ArithException a tryArith = unsafePerformIO . try . evaluate . flip using rnf
test :: [Either ArithException Integer] test = map (tryArith . (div 5)) [2,1,0,5]
testResult = [Right 2,Right 5,Left DivideByZero,Right 1]
withPair :: Integer -> (Integer,Integer) withPair x = (x,throw Overflow)
main = do print (test == testResult) print (tryArith (withPair 7)) print (tryArith' (withPair 7))
in ghci
*Main> main main True Left arithmetic overflow Right (7,*** Exception: arithmetic overflow
This "rnf :: Strategy a" ensures that the result of evaluate is in normal form. This means it should not have any embedded lazy thunks, so any errors from such thunks will be forced while in the scope of the "try".
Otherwise a complex type like the result of withPair can hide an error.
Thanks a lot. I found it is much easier to deal with Exception with this than convert all my code to monadic style. -- c/* __o/* <\ * (__ */\ <