10

this answer所示,在等式推理方面seq结合使用undefined会做非常奇怪的事情,例如它可以使任何单子失败。另一个例子是在这个问题中。

最近我偶然发现evaluate :: a -> IO a它做了类似的事情 - 它评估它对 WHNF 的论点,但仅在IO评估动作时。这似乎更安全,因为人们期望“IO我们可以做任何事情”。当然,它不能在任何地方使用,但通常需要评估表达式以某种方式与IO操作相关(例如在使用 s 时强制生成线程评估计算而不是消费线程MVar)。

所以我想问一下,安全性如何evaluate?是否有可能创建示例(IO当然涉及)它打破了对代码的推理seq?或者我可以将其视为seq(如果特定程序可能的话)的安全替代品吗?

4

1 回答 1

5

不,您仍然会遇到由命令引起的相同问题seq,因为在 的第一个参数中使用的任何 monadevaluate都会破坏其 monad 规则。根据ertes回答中的规则:

在 Kleisli 范畴中,monad 产生的return是恒等态射并且(<=<)是组合。所以return必须是一个身份(<=<)

return <=< x = x

这意味着您应该能够在不更改程序操作的情况下用任何有效的 monadreturn <=< x替换。x

将其与evaluate功能一起使用...

evaluate (return <=< undefined :: a -> Identity b) >> putStrLn "hello"

输出你好。使用 what 应该是等效的语句替换return <=< undefinedundefined

evaluate (undefined :: a -> Identity b) >> putStrLn "hello"

而是导致Prelude.undefined异常。

这只发生在评估功能上。请注意,return它的类型签名与evaluate. 如果您在上述命令中替换为 ,则两个命令的结果操作是相同的(它们输出evaluate)。returnhello

于 2012-12-08T03:58:03.753 回答