【问题标题】:Is the combination of `<$>`/`<*>`/`join` equivalent to `>>=`?`<$>`/`<*>`/`join` 的组合是否等同于 `>>=`?
【发布时间】:2020-10-24 08:22:54
【问题描述】:

据我了解,两种单子操作都应该具有同样的表现力:

(^2) >>= (\x -> if x == 4 then \_ -> [] else (+1) >>= (\y -> negate >>= (\z env -> [x, y, z, env]))) $ 2
--                             ^^    

join (((\x -> if x == 4 then \_ _ _ -> [] else \y z env -> [x, y, env, z]) <$> (^2)) <*> (+1)) <*> (negate) $ 2
--                           ^^^^^^

(请随意缩进上面的代码,因为我不知道如何在不破坏语法的情况下这样做)

两种计算产生相同的结果[],但是它们的不同之处在于只有后者短路,而前者必须经过整个结构。这不是问题,只要效果可以忽略并因此是幂等的,当然不是对所有可能的实例都成立。

我可能错误地使用了join,但我看不到如何通过应用计算获得短路。似乎短路语义来自于单子计算的嵌套结构。

【问题讨论】:

  • 我不确定我理解你所说的短路是什么意思。请记住,Haskell 具有非严格的语义,因此从某种角度来看,几乎任何东西都会短路,直到它不能再短路。除此之外,这是一个既定的数学事实,即一旦您拥有fmap(相当于&lt;$&gt;),您就可以相互定义join 和&gt;&gt;= 并获得完全相同的行为。如果你发现这个规则失效的 monad,你就发现了一个无效的 monad,你应该考虑向那个库的作者报告一个错误。
  • @SilvioMayolo 如果您使用join 作为其他应用计算的最外层操作,则您将两个上下文的合并推迟到计算结束,因此无法通过前一个值确定下一个效果。这仅在您将每次出现的&gt;&gt;= 替换为fmap 后跟join 时才有效,

标签: haskell functional-programming monads


【解决方案1】:

总是这样

join m = m >>= id
m >>= f = join (f <$> m)

您可以使用这些法则在join 和&gt;&gt;= 之间进行转换。

【讨论】:

  • 详细说明一下:通过将&gt;&gt;= 替换为join (f &lt;$&gt; m),我们可以保持相同的嵌套结构。
猜你喜欢
  • 2021-10-09
  • 2021-10-09
  • 1970-01-01
  • 2017-11-29
  • 2010-11-30
  • 2017-01-20
  • 2016-02-12
  • 1970-01-01
  • 2023-03-06
相关资源
最近更新 更多