[Haskell-cafe] Catch multiple exceptions using 'Control.Exception'

Nikita Karetnikov nikita at karetnikov.org
Sat Jul 6 18:12:58 CEST 2013


> Here you go:

>   import Control.Exception
>   import Data.Typeable

>   syncExceptions :: SomeException -> Maybe SomeException
>   syncExceptions e
>     | Just _ <- cast e :: Maybe AsyncException = Nothing
>     | otherwise = Just e

Thanks, but it doesn't work as expected:

*Main> syncExceptions $ toException StackOverflow
Just stack overflow

It should return 'Nothing' instead:

*Main> cast $ toException StackOverflow :: Maybe AsyncException
Nothing

I've received another solution, and it works fine.  I also have other
questions (see below).

-------------------- Start of forwarded message --------------------
From: "Albert Y. C. Lai" <trebla at vex.net>

[...]

import Control.Exception

syncExceptions :: SomeException -> Maybe SomeException
syncExceptions s = case fromException s :: Maybe AsyncException of
     Nothing -> Just s
     Just _ -> Nothing

testsync = tryJust syncExceptions (throwIO DivideByZero)
(is caught a Left)

testasync = tryJust syncExceptions (throwIO StackOverflow)
(is uncaught)

The change from the old scheme to the new scheme is, conceptually, from 
a closed sum type to an open existential type (SomeException); 
programmatically, from pattern-matching to type-casing aka downcasting 
(using fromException).

Therefore, changes to all call sites may be inevitable after all. For 
example:

   lr <- tryJust syncExceptions action
   case lr of
     Right n -> print n
     Left (IOException _) -> putStrLn "it's I/O"
     Left (ArithException _) -> putStrLn "it's arith"
     _ -> putStrLn "others"

must be changed to:

   lr <- tryJust syncExceptions action
   case lr of
     Right n -> print n
     Left s -> case fromException s :: Maybe IOException of
       Just _ -> putStrLn "it's I/O"
       Nothing -> case fromException s :: Maybe ArithException of
         Just _ -> putStrLn "it's arith"
         Nothing -> putStrLn "others"

at which point it is no longer clear that "preserving syncExceptions" 
implies "minimum global change". It may be better off to use catches 
afterall. Or still use tryJust but every call site uses a tailored-made 
predicate for that site rather than thinking that one single 
syncExceptions fits all.
-------------------- End of forwarded message --------------------

Could anyone elaborate on the following terms: "a closed sum type" and
"an open existential type"?  What is the meaning of the words "open" and
"closed"?  Is there an open sum type or a closed existential type?

Also, I thought that a sum type [1] should only have two value
constructors:

data Add a b = AddL a | AddR b

or

data Either a b = Left a | Right b

Is 'Exception' [2] a sum type?  If so, is it because of the associative
law?

[1] http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/
[2] http://hackage.haskell.org/packages/archive/base/4.1.0.0/doc/html/Control-OldException.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130706/c00895b2/attachment.pgp>


More information about the Haskell-Cafe mailing list