【问题标题】:What is the difference between *> and >> in Haskell?Haskell中的*>和>>有什么区别?
【发布时间】:2021-06-27 06:55:34
【问题描述】:

来自文档:

(>>) :依次组合两个动作,丢弃第一个动作产生的任何值

(*>) :序列动作,丢弃第一个参数的值。

在我看来,两者都在做同样的工作。

【问题讨论】:

  • 有一点需要注意:默认实现。默认情况下,m >> n = m >>= const nm *> n = liftA2 (flip const) m n。对于许多 monad,它们具有完全不同的性能特征!在这些情况下,您应该确保明确定义默认情况下性能不佳的那些。

标签: haskell monads applicative


【解决方案1】:

实际上它们是等价的。

从历史上看,Haskell 没有Applicative 类型类(因此没有*>),而只有Monad 类型类(带有>>)。

在某一时刻,Applicative 成为Monad 的超类。那时,*> 作为>> 的一个更通用的变体被引入,它不需要使用 monad,而只需要使用 applicative functor。

(*>) :: Applicative f => f a -> f b -> f b
(>>) :: Monad f       => f a -> f b -> f b

最终结果是,在使用应用程序时,我们只能使用 *>,而在使用 monad(也是应用程序)时,我们可以交替使用 *>>>,因为它们需要在这种情况下是等价的。

其他几个与 monad 相关的函数也被类似地推广到应用程序:

  • returnpure 概括
  • ap<*> 泛化
  • mapMtraverse 概括

【讨论】:

  • “必需”(或者只是“强烈鼓励”?)在语义上是等价的,但可能存在操作上的差异,例如 *> 被允许这样做也许它的东西是平行的?
  • @WillNess 当然,可能存在一些性能差异。 monad 和 applicative 法则只要求语义相同,就像往常一样。尽管如此,如果它们以不同的方式实现,并且对于同一个 monad 具有显着的性能差异,那将是非常奇怪的。如果一种实现性能更高,人们会期望另一种实现被替换。
  • hmm...这是否意味着>> 可以并行运行效果(如果这对特定类型有意义)?
  • @WillNess 仅当它在语义上仍然等效时。对于IO,例如,它不是。
  • 一个小的修正:*> 运算符在成为Monad 的超类之前是Applicative 的一部分(请参阅base-4.7.0.0)。所以,历史是:(1)Haskell 只有Monad>>; (2) Applicative 引入对应的*> 运算符; (3) Applicative 成为Monad 的超类,之后它们在实践中是等价的。
猜你喜欢
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 2016-08-07
  • 2016-05-16
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2017-06-17
相关资源
最近更新 更多