我无法理解如何使用断言函数(Control.Exception.Assert)
我确实阅读了文档(http://hackage.haskell.org/package/assert-0.0.1.2/docs/Control-Exception-Assert.html),但我似乎仍然不明白它的用法。在这种情况下,这种欺骗实际上并没有帮助,因为它不够明确。举例和解释它的用途会很可爱。
(对于上下文,我试图弄清楚如何在此代码中使用assert,以确保n始终为非负数)[请无人回答,我想自行解决]
power :: Int -> Int -> Int
power x n =
if n == 0 then
1
else
x * power x (n - 1)
答案 0 :(得分:6)
从该库导出的assert
(我没有使用过)实际上是在base
here中定义的。您可以像这样使用它:
power :: Int -> Int -> Int
power x n = assert (n >= 0) $
if n == 0 then
1
else
x * power x (n - 1)
但这并不是该功能的真正含义。在上述情况下,最好是通过友好的信息引发您自己的错误,或者(更好)返回一个Maybe Int
。
assert
用于检查函数中的内部不变量,其中违反表示错误。将断言与测试(测试内部不变式进行测试,这些内部不变式由内部assert
调用进行检查)结合使用会非常有用。
不过,您必须确保不进行优化也可以使用-fno-ignore-asserts
进行编译,因为使用优化进行编译时会断言断言(assert
的另一个强大功能)。
我已经开始在库代码中包含以下 以便测试我的测试套件中是否存在断言(非常重要,这是我之前遇到的一个问题):
assertionCanary :: IO Bool
assertionCanary = do
assertionsWorking <- try $ assert False $ return ()
return $
case assertionsWorking of
Left (AssertionFailed _) -> True
_ -> False
答案 1 :(得分:3)
将assert
视为条件身份函数。如果第一个参数为false,则会引发异常。否则,返回第二个参数。一个实现可能看起来像
assert :: Bool -> a -> a
assert True = id
assert False = \_ -> error "Assertion Failed" -- const (error "Assertion Failed")
(我不确定使用它来给出哪个示例不会有效地放弃如何编写power
。