【问题标题】:What is the point of the Functor -> Applicative -> Monad hierarchy [duplicate]Functor -> Applicative -> Monad层次结构的意义是什么[重复]
【发布时间】:2022-01-02 07:07:53
【问题描述】:

让 Functor 成为 Applicative 和 Monad 的超类有什么意义。据我所知,Applicative 和 Monad 都立即暗示了 Functor 的唯一实现。但是我每次都必须输入相同的 Functor 实现。有没有办法避免这样做?

还有更多 Monad 意味着 Applicative 的唯一实现遵守法律那么为什么让 Applicative 成为 Monad 的超类?它再次使为新数据类型实现 Applicative 变得多余。

有没有一种方法可以在不必实现 Applicative 和 Functor 的情况下制作 Monad(因为它的操作已经是最通用的了)。并且无需实现 Functor 即可制作 Applicative。

我看到了类层次结构的好处,因为我刚才所说的解释了它们之间的“是”关系。但同时必须实现每一个都很烦人。我只想定义return>>= 并将所有3 的所有操作都返回。

【问题讨论】:

标签: haskell monads functor applicative default-method


【解决方案1】:

您可以通过这种方式获取这些实例:

import Control.Applicative
data Whatever a = {- ... -} deriving (Functor, Applicative) via (WrappedMonad Whatever)

在编译器违反规范时将DefaultSignatures 默认值添加到FunctorApplicative 类会很好,这样您甚至不需要编写via WrappedMonad,但现在它已经完成了,我怀疑我们永远不会得到它们。太糟糕了。

【讨论】:

  • 请不要通过WrappedMonad派生Functorstock 派生它要好得多。 (对于Applicative,直接实现实例也总是值得考虑,而不是捎带在Monad 上可能效率较低。)
  • Applicative 在通过 (issue) 派生之前无法派生,因为他们删除了 return 作为不归路的一部分。如果你尝试使用pure @Whatever,它会出现分歧!
【解决方案2】:

编写ApplicativeMonad 实例的成本只需由实施者支付一次。然而,没有这些实例的成本由用户一次又一次地承担。考虑一个使用Applicative 的组合器,例如traverse

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

如果没有超类关系,我们选择f 作为Monad 将不足以让我们使用traverse。我们最终需要traverseMonad 特定版本(即mapM),并基于几乎总是无关紧要的区别从一个切换到另一个。将Applicative 作为Monad 的超类意味着我们不必为此烦恼。

【讨论】:

    猜你喜欢
    • 2012-01-29
    • 2011-11-05
    • 2012-11-12
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 2013-11-07
    相关资源
    最近更新 更多