assert在return()中没有求值



我有以下代码片段,其中assert用于检查有关某些内部状态的不变量。然而,assert永远不会被求值,因此即使在应该求值的时候也不会失败,这可能是因为当返回类型()时,return不会被求值。即使我更改为assert False,这也成立。有办法解决这个问题吗?

FooM :: m () // m is a monad
FooM = do
state <- get
// some state mutation
state' <- get
return $ assert (state /= state') ()
return $ assert False () // <-- this also never fails

return $ assert (state /= state') ()被求值,因为一元的>>=需要求值以确定"执行什么";(碰巧那是"没什么")。但是,尽管操作被求值,但是该操作中包含的assert (state /= state') ()没有被求值,因为它没有被使用。解决方案是用assert来保护动作return (),而不是(被忽略的)值()

assert (state /= state') $ return ()

或者

return $! assert (state /= state') ()
-- = let arg = assert (state /= state') () in arg `seq` return arg
-- for evaluation to "get to" the return, the assertion must succeed

相关内容

  • 没有找到相关文章

最新更新