这里有一些值得思考的东西.
当我编写monadic代码时,monad会对完成的操作进行排序.例如,如果我写入IO monad:
do a <- doSomething
b <- doSomethingElse
return (a + b)
Run Code Online (Sandbox Code Playgroud)
我知道doSomething以前会被执行doSomethingElse.
现在,考虑像C这样的语言中的等效代码:
return (doSomething() + doSomethingElse());
Run Code Online (Sandbox Code Playgroud)
C的语义实际上没有指定这两个函数调用将被评估的顺序,因此编译器可以随意移动它.
我的问题是这样的:我如何在Haskell中编写monadic代码,这也使得这个评估顺序未定义?理想情况下,当编译器的优化器查看代码并开始移动时,我会获得一些好处.
以下是一些可能无法完成工作的技术,但却是正确的"精神":
plus doSomething doSomethingElse并plus调度monadic调用.缺点:你失去了对monadic动作结果的分享,并且plus仍然决定什么时候最终会被评估.unsafeInterleaveIO调度推迟到评估的懒惰需求.但懒惰不同于严格的未定义顺序:特别是我确实希望我的所有monadic动作都被执行.seq不强加排序约束.从这个意义上讲,我想要一些比一元顺序更灵活的东西,但是比完全懒惰更不灵活.