Haskell的异常处理机制是如何工作的?

10
foldl1 (+) []

我该如何捕获产生的错误?


2
请参见https://dev59.com/OnA65IYBdhLWcg3wxRo8。 - Chris Smith
没关系,安全失败库统治世界只是时间问题 ;-). - Thomas M. DuBuisson
@qrest http://hackage.haskell.org/package/safe-failure - Lambda Fairy
3个回答

14

纯代码可能会抛出异步的、不精确的异常,例如当部分函数遇到无法处理的输入时。

这些通常是逻辑错误,表明程序规范中存在错误。

它们可以通过异常处理程序在 IO 代码(通常在程序的外层)中捕获。

例如,要捕获空列表的缺失情况:

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns        #-}

import Control.Exception

main = do
    handle (\(e :: SomeException) -> print $ "This program as a bug: " ++ show e) $ do
        let !v = foldl1 (+) ([] :: [Int])
        return ()

我们可以观察到异常被捕获,程序终止。
$ ./A
"This program as a bug: Prelude.foldl1: empty list"

4
我认为该程序的异常处理器也有一个 bug :-) - Simon Marlow
这次交流给了我很多快乐。 - sclv

6

4
纯洁主义者的回答:结果未定义(具体来说,bottom)。你不能对它做任何事情,除非该值在构建程序结果的任何方式中使用,否则会崩溃。请参阅Haskell 98报告第3.1节。它指定这种“错误会导致立即终止程序,用户无法捕获”。
最好在输入值到达此处之前检查并处理它们。如果列表可能有0个元素,请勿使用fold1。
但在实践中,您可以使用其他答案中的方法在使用GHC时在IO中捕获它。异常无法在纯(非IO)代码中捕获,因为引发异常是控制流的变化是副作用,而不是纯计算。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接