Reputation: 9354
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
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