ron
ron

Reputation: 9354

How to rethrow generic exception in Haskell

Given

f :: Int -> IO (Either SomeException Int)

g = do
  results <- mapM f [1,2,3]
  let (errs, succs) = partitionEithers results
  if null errs then return succs
               else  -- rethrow arbitrary exception
                     throwIO (fromJust . fromException $ head errs)

I would have expected g to rethrow whatever exception it encounters, however compilation fails with ambigous type variable. Sprinkling randomly with existential quantified helpers doesn't help.

How can I rethrow an arbitrary exception I encounter without loosing genericity?

Upvotes: 3

Views: 657

Answers (1)

Carl
Carl

Reputation: 27003

Just use throwIO $ head errs.

The error message is because fromException needs to go to a type known at compile time. You provide no context for it to figure out what type it is, so it complains that the type variable is ambiguous.

Fortunately, you don't need to know what type it is. SomeException is an instance of Exception, too. It can be rethrown without ever knowing what type it contains. In fact, if you look at the definition of the Exception class, it's just toException and fromException, which are conversion functions that lean on Typeable to ensure that they don't break the type system. SomeException's instance for Exception just has the most boring possible definitions for those.

Upvotes: 3

Related Questions