以下是一些值得思考的内容。
当我编写单子代码时,单子会对所执行的操作进行排序。例如,如果我在IO单子中编写:
do a <- doSomething
b <- doSomethingElse
return (a + b)
我知道doSomething
会在doSomethingElse
之前执行。
现在,考虑类似C语言的等效代码:
return (doSomething() + doSomethingElse());
C语言的语义实际上并未指定这两个函数调用的顺序,因此编译器可以自由地移动它所需的内容。
我的问题是:我该如何在Haskell中编写monadic代码,同时也将这种评估顺序保持为undefined?理想情况下,当我的编译器优化器查看代码并开始移动内容时,我希望获得一些好处。
以下是一些可能的技术,虽然没有完成任务,但都符合正确的“精神”:
- 以函子风格编写代码,即编写
plus doSomething doSomethingElse
,并让plus
安排monadic calls。缺点:您会失去monadic actions结果的共享,并且plus
仍然会决定何时进行评估。 - 使用lazy IO,即
unsafeInterleaveIO
,将调度推迟到评估的需求。但lazy和strict with undefined order是不同的:特别是我确实希望执行所有monadic actions。 - Lazy IO,结合立即seq'ing所有参数。特别地,
seq
不会强制排序约束。
在这种意义上,我需要比monadic ordering更灵活但比全面的laziness不那么灵活的东西。