88

在 GHCi 中:

Prelude> error (error "")
*** Exception: 
Prelude> (error . error) ""
*** Exception: *** Exception: 

为什么第一个不是嵌套异常?

4

1 回答 1

103

答案是,这是不精确异常的(有点令人惊讶的)语义

当纯代码可以显示为一异常值(即 erroror的值undefined,并且明确不是在 IO 中生成的那种异常)时,该语言允许返回该组的任何值。Haskell 中的异常值更像NaN是浮点代码,而不是命令式语言中基于控制流的异常。

即使是高级 Haskellers,偶尔也会遇到一个问题,例如:

 case x of
   1 -> error "One"
   _ -> error "Not one"

由于代码评估为一组异常,GHC 可以自由选择一个。启用优化后,您可能会发现这总是评估为“不是”。

我们为什么要做这个?因为否则我们会过度限制语言的评估顺序,例如,我们必须为以下情况修复确定性结果:

 f (error "a") (error "b")

例如,如果存在错误值,则要求从左到右进行评估。非常不合时宜!

由于我们不想削弱可以对我们的代码进行的优化以支持error,因此解决方案是指定结果是一组异常值中的非确定性选择:不精确的异常!在某种程度上,所有的异常都会被返回,并选择一个。

通常,您不关心 - 异常就是异常 - 除非您关心异常中的字符串,在这种情况下使用error调试非常混乱。


参考文献:不精确异常的语义,Simon Peyton Jones、Alastair Reid、Tony Hoare、Simon Marlow、Fergus Henderson。Proc 编程语言设计和实现 (PLDI'99),亚特兰大。( PDF )

于 2012-06-17T16:29:05.047 回答