鉴于
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)
我原本希望g
能够重新抛出它遇到的任何异常,但编译失败时会出现ambigous类型变量。与存在量化的助手一起随机洒水无济于事。
如何在不失去通用性的情况下重新抛出我遇到的任意异常?
答案 0 :(得分:3)
只需使用throwIO $ head errs
。
错误消息是因为fromException
需要转到编译时已知的类型。你没有提供任何上下文来确定它是什么类型,所以它抱怨类型变量是不明确的。
幸运的是,你不需要知道它是什么类型。 SomeException
也是Exception
的一个实例。它可以在不知道它包含什么类型的情况下重新生成。事实上,如果你看一下Exception
类的定义,它只是toException
和fromException
,这些转换函数依赖于Typeable
以确保它们不会“打破类型系统。 SomeException
Exception
的实例只有最无聊的可能定义。