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

Pet*_*lák 10 haskell lazy-evaluation seq

正如这个答案所示,当涉及到等式推理时,seq结合undefined非常奇怪的事情,例如它可以使任何monad失败.另一个例子就是这个问题.

最近我偶然发现evaluate :: a -> IO a了类似的事情 - 它评估了它对WHNF的论证,但仅在IO评估行动时.这似乎更安全,因为人们期望"在IO我们能做的一切".当然它不能在任何地方使用,但通常需要评估表达式以某种方式与IO操作连接(比如强制生成线程在使用MVars 时评估计算而不是消耗线程).

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

Dav*_*ani 5

不,你仍然得到由seq命令引起的相同问题,因为在第一个参数中使用的任何monad evaluate将使其monad规则被破坏.在ertes的答案中取消规则:

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

return <=< x = x
Run Code Online (Sandbox Code Playgroud)

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

使用它与evaluate功能...

evaluate (return <=< undefined :: a -> Identity b) >> putStrLn "hello"
Run Code Online (Sandbox Code Playgroud)

输出你好.通过替换return <=< undefinedundefined:使用什么应该是等效语句:

evaluate (undefined :: a -> Identity b) >> putStrLn "hello"
Run Code Online (Sandbox Code Playgroud)

而是导致Prelude.undefined异常.

这只发生在evaluate函数中.请注意,它return具有完全相同的类型签名evaluate.如果更换evaluatereturn在上面的命令,两个命令的结果的动作是相同的(它们的输出hello).