[Haskell-cafe] Re: Use unsafePerformIO to catch Exception?

Xiao-Yong Jin xj2106 at columbia.edu
Mon Mar 23 09:50:11 EDT 2009


ChrisK <haskell at list.mightyreason.com> writes:

> 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/*
    <\     * (__
    */\      <


More information about the Haskell-Cafe mailing list