Haskell 如何使用断言?
我很难理解如何使用assert函数(Control.Exception.assert) 我确实阅读了文档(),但我似乎仍然不明白它是如何使用的。在这种情况下,咖喱真的没有帮助,因为它是多么的不可解释。举例说明它的用途会很好 (在上下文中,我试图弄清楚如何在代码中使用assert来确保n始终是非负的)[请不要回答,我想自己弄清楚]Haskell 如何使用断言?,haskell,Haskell,我很难理解如何使用assert函数(Control.Exception.assert) 我确实阅读了文档(),但我似乎仍然不明白它是如何使用的。在这种情况下,咖喱真的没有帮助,因为它是多么的不可解释。举例说明它的用途会很好 (在上下文中,我试图弄清楚如何在代码中使用assert来确保n始终是非负的)[请不要回答,我想自己弄清楚] power :: Int -> Int -> Int power x n = if n == 0 then 1 else x * p
power :: Int -> Int -> Int
power x n =
if n == 0 then
1
else
x * power x (n - 1)
将
assert
视为一个条件标识函数。如果第一个参数为false,则引发异常。否则,将返回第二个参数。实现可能类似于
assert :: Bool -> a -> a
assert True = id
assert False = \_ -> error "Assertion Failed" -- const (error "Assertion Failed")
(我不确定使用它的哪个示例不会有效地泄露如何编写
power从该库导出的assert
(我没有使用过)实际上是在base
中定义的。您可以这样使用它:
power :: Int -> Int -> Int
power x n = assert (n >= 0) $
if n == 0 then
1
else
x * power x (n - 1)
但这并不是函数的真正目的。在上述情况下,最好用友好的消息引发您自己的错误,或者(更好的是)返回一个可能是Int
assert
用于检查函数中的内部不变量,如果出现冲突则表示存在错误。将断言与测试结合使用(测试执行由内部assert
调用检查的不变量)非常有用
您必须确保编译时不使用优化或使用-fno ignore asserts
,因为使用优化编译时会优化断言(assert
的另一个重要功能)
我在库代码中包含了以下内容,以便在我的测试套件中进行断言测试(非常重要,我以前遇到过这个问题):
assertionCanary::IO Bool
assertionCanary=do
断言是正确的
_->错误
如果你不想修改power
的主体,你可以在它前面加上等式power\n\124; assert(n>=0)False=undefined
(这个技巧是由于Oleg:)。是的,我意识到没有这个例子可能很难解释这一点,所以谢谢!
assertionCanary :: IO Bool
assertionCanary = do
assertionsWorking <- try $ assert False $ return ()
return $
case assertionsWorking of
Left (AssertionFailed _) -> True
_ -> False