Haskell中异常的含义是什么?我看到的唯一用法是输入 undefined
或 error
在我的代码中阻止程序运行。否则,我将异常编程视为逻辑设计缺陷。但是 Haskell 有一个高级异常模块 Control.Exception
由 Prelude
使用.我读到 C++ 中出现异常的原因是为了防止代码中出现大量“调用函数,然后检查状态”行。但是这些东西可以在 Haskell 中抽象出来。我可以看到在 Haskell 中进行异常处理的唯一其他原因是使用 FFI 来处理外部异常,但仅用于包装调用的 Haskell 函数的内部使用。
最佳答案
在我看来,异常(exception)意味着“你违反了函数的契约(Contract)”。我不是在谈论类型契约(Contract),而是在谈论您通常在评论中找到的东西。
-- The reciprocal is not defined for the value 0
myRecip :: Fractional a => a -> a
myRecip x | x == 0 = throw DivideByZero
| otherwise = 1 / x
当然,您始终可以以“安全”的方式提供此功能:
safeRecip :: Fractional a => a -> Maybe a
safeRecip x | x == 0 = Nothing
| otherwise = Just $ 1 / x
或许我们甚至应该抽象出这种模式
restrictInput :: (a -> Bool) -> (a -> b) -> (a -> Maybe b)
restrictInput pred f x = if pred x then Just (f x) else Nothing
safeRecip' = restrictInput (/= 0) myRecip
您可以想象使用
Either
的类似组合子。而不是 Maybe
报告失败。那么既然我们有能力用纯函数处理这些事情,为什么还要为不纯的异常模型烦恼呢?好吧,大多数 Haskeller 会告诉你要坚持纯洁。但黑暗的事实是,添加额外的层只是一种痛苦。你不能再写了prop_recip x = x == (recip . recip) x
因为现在
recip x
的结果位于 Maybe
.您可以使用 (a -> a)
做一些有用的事情你不能再做的功能。现在你必须考虑创作Maybes。当然,如果您对 monad 感到满意,这将是微不足道的:prop_recip 0 = (safeRecip >=> safeRecip) 0 == Nothing
prop_recip x = (safeRecip >=> safeRecip) x == Just x
但问题就在这里。当涉及到一元组合时,新手通常几乎一无所知。 Haskell 委员会,正如#haskell irc channel 上的许多人会很快告诉你的那样*,为了迎合新手,在语言设计方面做出了一些相当不稳定的决定。我们希望能够说“你不需要知道 monad 就可以开始在 Haskell 中制作有用的东西”。我大体上同意这种观点。
tl;博士
对这个问题的一些快速回答:什么是异常(exception)?
可能还有其他解释。
另见 Haskell Report > Basic Input/Output > Exception Handling in the IO Monad
*我实际上在#haskell irc 上问过他们是否同意这一声明。我得到的唯一回复是
"wonky" :)
因此,没有异议显然证明了它是正确的。[编辑] 注意
error
和 undefined
根据 throw
定义:error :: [Char] -> a
error s = throw (ErrorCall s)
undefined :: a
undefined = error "Prelude.undefined"
关于haskell - Haskell 异常的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7704999/