在GHCi中:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
为什么第一个不是嵌套异常?
在GHCi中:
Prelude> error (error "")
*** Exception:
Prelude> (error . error) ""
*** Exception: *** Exception:
为什么第一个不是嵌套异常?
error
是特殊的,并不是真正的异常机制。有关真正的,可捕获的异常,请参见Error
monad。
(\f g x -> f (g x)) error error ""
行为也不同于。可能与Prelude编译时使用的优化标志有关。(.) error error ""
(.)
iterate error "" !! n
真棒fix error
。
error = error
并相应地编程。
Answers:
答案是,这是不精确异常的(有点令人惊讶)语义
当纯代码可以显示为一组异常值(即error
或的值 undefined
,而明确地不是IO中生成的异常的类型)时,则该语言允许返回该组的任何值。Haskell中的异常值更像NaN
是浮点代码,而不是命令式语言中基于控制流的异常。
甚至对于高级Haskeller来说,偶尔也会遇到这样的情况:
case x of
1 -> error "One"
_ -> error "Not one"
由于代码会评估一组异常,因此GHC可以自由选择一个。启用优化后,您很可能会发现此结果始终为“ Notone”。
我们为什么要做这个?因为否则我们会过度限制语言的评估顺序,例如,我们将不得不为以下问题确定确定性的结果:
f (error "a") (error "b")
例如,如果存在错误值,则要求从左到右进行评估。非常不客气!
由于我们不想牺牲仅仅为了支持代码而可以进行的优化error
,因此解决方案是指定结果是一组异常值中的不确定性选择:不精确的异常!以某种方式,将返回所有异常,然后选择一个。
通常,您不在乎-异常就是异常-除非您关心异常内的字符串,否则在这种情况下使用error
调试会造成极大的混乱。
参考文献:不精确异常的语义,Simon Peyton Jones,Alastair Reid,Tony Hoare,Simon Marlow,Fergus Henderson。Proc编程语言设计与实现(PLDI'99),亚特兰大。(PDF)
throw
),您可以确定地使用引发异常throwIO
。
case error "banana" of (x:xs) -> error "bonobo"
可以给你* Exception: bonobo
。