Haskell中的exception如何工作?

在GHCi:

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

为什么不是第一个嵌套exception?

答案是,这是不准确的例外 (有点令人惊讶)的语义

当纯代码可以显示为一exception值(即errorundefined的值,显式不是 IO中生成的exception的types)时,则该语言允许返回该集合的任何值。 Haskell中的exception值更像是浮点代码中的NaN ,而不是命令式语言中基于控制stream的exception。

甚至对于高级Haskellers来说偶尔也是一个例子,例如:

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

由于代码评估为一组例外,GHC可以自由select一个。 随着优化,你可能会发现这总是评估为“不是一个”。

我们为什么要做这个? 否则,我们会过度地限制语言的评估顺序,例如,我们将不得不修复确定性结果:

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

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

由于我们不想削弱为了支持error对代码进行的优化,因此解决scheme是指定结果是一组非常确定的选项:不精确的exception! 在某种程度上,所有例外都被返回,并且select一个例外。

通常情况下,你不关心 – exception是一个exception – 除非你关心exception内的string,在这种情况下,使用errordebugging是非常混乱。


参考文献: 不精确的例外语义 ,西蒙·佩顿·琼斯,阿拉斯泰尔·里德,托尼·霍尔,西蒙·马洛,弗格斯·亨德森。 Proc编程语言devise和实现(PLDI'99),亚特兰大。 ( PDF )