断言未在 return () 中求值
assert is not evaluated in 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') ()
是 评估,因为 monadic >>=
需要评估它以确定“执行什么”(恰好是没什么”)。但是,虽然 action 被评估了,但该操作中包含的 value assert (state /= state') ()
没有被评估,因为它没有被使用。解决方案是用 assert
保护 action 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
我有以下代码片段,其中 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') ()
是 评估,因为 monadic >>=
需要评估它以确定“执行什么”(恰好是没什么”)。但是,虽然 action 被评估了,但该操作中包含的 value assert (state /= state') ()
没有被评估,因为它没有被使用。解决方案是用 assert
保护 action 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