【问题标题】:How does Haskell exception handling work?Haskell 异常处理是如何工作的?
【发布时间】:2025-11-29 01:25:02
【问题描述】:
foldl1 (+) []

如何捕获由此产生的错误?

【问题讨论】:

标签: exception haskell exception-handling


【解决方案1】:

纯代码可能会抛出异步,imprecise exceptions,例如,当部分函数遇到输入时,它没有要处理的情况。

这些是逻辑错误,通常表示程序规范中的错误。

它们可能通过exception handler 被 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"

【讨论】:

  • 我认为该程序也作为其异常和错误中的一个错误 :-)
  • 这次交流让我很开心。
【解决方案2】:

【讨论】:

    【解决方案3】:

    纯粹的答案:结果未定义(具体来说,bottom)。如果以任何方式使用该值来构建程序的结果,则除了崩溃之外,您无法对其进行任何操作。见Haskell 98 Report section 3.1。它指定此类“错误会导致程序立即终止并且用户无法捕获”。

    最好检查输入值并在它们到达之前处理它们。如果列表可能有 0 个元素,请不要使用 fold1。

    但实际上,您可以在使用 GHC 时使用其他答案中的方法在 IO 中捕获它。不能在纯(非 IO)代码中捕获异常,因为引发异常是控制流的变化是副作用,而不是纯计算。

    【讨论】:

      最近更新 更多