与`seq`相比,`evaluate`安全吗?

时间:2012-12-07 21:35:11

标签: haskell lazy-evaluation seq

作为shown in this answersequndefined相结合,在涉及等式推理方面做了非常奇怪的事情,例如它可以使任何monad失败。另一个例子是this question

最近我偶然发现evaluate :: a -> IO a做了类似的事情 - 它只评估了WHNF的参数,但只评估了IO动作。这似乎更安全,因为人们期望“在IO我们可以做任何事情”。当然它不能在任何地方使用,但通常需要评估表达式以某种方式与IO操作连接(比如强制生成线程在使用{{1}时评估计算而不是消耗线程} S)。

所以我想问一下,MVar有多安全?是否有可能创建示例(当然涉及evaluate),它会破坏像IO这样的代码的推理?或者我可以将其视为seq的安全替代品(如果特定程序可能的话)?

1 个答案:

答案 0 :(得分:5)

不,您仍然会遇到seq命令导致的相同问题,因为evaluate的第一个参数中使用的任何monad都会破坏其monad规则。在ertes的答案中取消规则:

  

在Kleisli类别中,monad引起return   身份态射和(<=<)是构成。所以return必须是一个   (<=<)的身份:

return <=< x = x

这意味着您应该能够将return <=< x替换为x任何有效的monad,而无需更改程序的操作。

将其与evaluate功能...

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

输出你好。通过将return <=< undefined替换为undefined来使用应该是等效语句:

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

会导致Prelude.undefined例外。

这只发生在evaluate函数中。请注意,returnevaluate具有完全相同的类型签名。如果在上述命令中将evaluate替换为return,则两个命令的结果操作相同(它们输出hello)。