断言如何使用?

时间:2018-09-07 17:28:30

标签: haskell

我无法理解如何使用断言函数(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)

2 个答案:

答案 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