haskell - 放松一元计算中的排序约束

标签 haskell monads commutativity

这里有一些值得深思的地方。

当我编写 monadic 代码时,monad 会对完成的操作进行排序。例如,如果我在 IO monad 中编写:

do a <- doSomething
   b <- doSomethingElse
   return (a + b)

我知道doSomething将在 doSomethingElse 之前执行.

现在,考虑类似 C 语言的等效代码:
return (doSomething() + doSomethingElse());

C 的语义实际上并没有指定这两个函数调用的评估顺序,因此编译器可以随意移动。

我的问题是:我将如何在 Haskell 中编写单子(monad)代码,这也使这个评估顺序未定义? 理想情况下,当我的编译器的优化器查看代码并开始移动时,我会获得一些好处。

以下是一些可能无法完成工作但具有正确“精神”的技术:
  • 写成函数式的代码,即写plus doSomething doSomethingElseplus安排单子(monad)调用。缺点:您无法共享单子(monad)操作的结果,并且 plus仍然会决定何时对事物进行评估。
  • 使用惰性IO,即unsafeInterleaveIO ,这将调度推迟到评估懒惰的需求。但是惰性与未定义顺序的严格不同:特别是我确实希望我的所有一元 Action 都能被执行。
  • 惰性 IO,结合立即对所有参数进行排序。特别是,seq不施加排序约束。

  • 从这个意义上说,我想要一些比一元排序更灵活但不如完全惰性的东西。

    最佳答案

    这个过度序列化 monad 代码的问题被称为 "commutative monads problem" .

    Commutative monads are monads for which the order of actions makes no difference (they commute), that is when following code:


    do a <- f x
       b <- g y
       m a b
    

    是相同的:
    do b <- g y
       a <- f x
       m a b
    

    有许多通勤的单子(monad)(例如 MaybeRandom )。例如,如果 monad 是可交换的,那么在其中捕获的操作可以并行计算。它们非常有用!

    但是,我们 对于通勤的 monad 没有良好的语法 , 虽然 a lot of people have asked对于这样的事情——它仍然是 open research problem .

    顺便说一句,应用仿函数确实给了我们重新排序计算的自由,但是,你必须放弃 bind 的概念。 (作为建议,例如 liftM2 显示)。

    关于haskell - 放松一元计算中的排序约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5897845/

    相关文章:

    haskell - 对 "Learn you a Haskell"上的 State Monad 代码感到困惑

    haskell - haskell 中最快的错误单子(monad)是什么?

    java - 有没有办法在php中使用交换加密?

    Swift - 具有可交换性的模式匹配

    haskell - 是否可以在 gtk2hs 中使用 Glade 创建的菜单?

    list - haskell - 指定为真的条件数

    haskell - Haskell 中附加词的用例

    haskell - `join` 和 `fmap join` 在 Haskell 中是否相等(从范畴论的角度来看)?

    haskell - Haskell Cont monad 如何以及为什么工作?

    javascript - JavaScript 中 reduceRight 的原生实现是错误的