如何在Haskell中重新抛出泛型异常

时间:2014-02-27 23:44:33

标签: exception haskell

鉴于

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类型变量。与存在量化的助手一起随机洒水无济于事。

如何在不失去通用性的情况下重新抛出我遇到的任意异常?

1 个答案:

答案 0 :(得分:3)

只需使用throwIO $ head errs

错误消息是因为fromException需要转到编译时已知的类型。你没有提供任何上下文来确定它是什么类型,所以它抱怨类型变量是不明确的。

幸运的是,你不需要知道它是什么类型。 SomeException也是Exception的一个实例。它可以在不知道它包含什么类型的情况下重新生成。事实上,如果你看一下Exception类的定义,它只是toExceptionfromException,这些转换函数依赖于Typeable以确保它们不会“打破类型系统。 SomeException Exception的实例只有最无聊的可能定义。