如何证明单子是一个函子和一个应用函子?

发布于 2025-01-01 09:25:05 字数 218 浏览 5 评论 0原文

理论上,Monad 是函子和具体应用函子的子集,尽管 Haskell 的类型系统中没有指出这一点。

知道了,给定一个 monad 并基于 returnbind,如何:

  • 导出 fmap
  • 导出 <*>< /代码>?

Monads are known to be theoretically a subset of functors and specifically applicative functors, even though it's not indicated in Haskell's type system.

Knowing that, given a monad and basing on return and bind, how to:

  • derive fmap,
  • derive <*> ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹏半生如梦愿梦如真 2025-01-08 09:25:05

嗯,fmap 只是 (a -> b) ->发-> f b,即我们想用纯函数转换一元动作的结果。使用 do 符号很容易编写:

fmap f m = do
  a <- m
  return (f a)

或者写成“raw”:

fmap f m = m >>= \a -> return (f a)

这可以作为 Control.Monad.liftM

纯::a -> f a 当然是return(<*>) :: f (a -> b) ->发-> f b 有点棘手。我们有一个返回函数的操作,还有一个返回其参数的操作,并且我们希望有一个返回其结果的操作。再次用 do 表示法:

mf <*> mx = do
  f <- mf
  x <- mx
  return (f x)

或者,脱糖:

mf <*> mx =
  mf >>= \f ->
  mx >>= \x ->
  return (f x)

Tada!这可以作为 Control.Monad.ap,因此我们可以为任何 monad M 提供 FunctorApplicative 的完整实例> 如下:

instance Functor M where
  fmap = liftM

instance Applicative M where
  pure = return
  (<*>) = ap

理想情况下,我们能够直接在 Monad 中指定这些实现,以减轻为每个 monad 定义单独实例的负担,例如使用 此提案。如果发生这种情况,那么使 Applicative 成为 Monad 的超类就不存在任何真正的障碍,因为它将确保它不会破坏任何现有代码。另一方面,这意味着为给定的 Monad 定义 Functor 和 Applicative 实例所涉及的样板是最少的,因此很容易一个“好公民”(并且应该为任何单子定义这样的实例)。

Well, fmap is just (a -> b) -> f a -> f b, i.e. we want to transform the monadic action's result with a pure function. That's easy to write with do notation:

fmap f m = do
  a <- m
  return (f a)

or, written "raw":

fmap f m = m >>= \a -> return (f a)

This is available as Control.Monad.liftM.

pure :: a -> f a is of course return. (<*>) :: f (a -> b) -> f a -> f b is a little trickier. We have an action returning a function, and an action returning its argument, and we want an action returning its result. In do notation again:

mf <*> mx = do
  f <- mf
  x <- mx
  return (f x)

Or, desugared:

mf <*> mx =
  mf >>= \f ->
  mx >>= \x ->
  return (f x)

Tada! This is available as Control.Monad.ap, so we can give a complete instance of Functor and Applicative for any monad M as follows:

instance Functor M where
  fmap = liftM

instance Applicative M where
  pure = return
  (<*>) = ap

Ideally, we'd be able to specify these implementations directly in Monad, to relieve the burden of defining separate instances for every monad, such as with this proposal. If that happens, there'll be no real obstacle to making Applicative a superclass of Monad, as it'll ensure it doesn't break any existing code. On the other hand, this means that the boilerplate involved in defining Functor and Applicative instances for a given Monad is minimal, so it's easy to be a "good citizen" (and such instances should be defined for any monad).

黯然#的苍凉 2025-01-08 09:25:05

fmap = liftM(<*>) = ap。以下是 源代码的链接liftMap。我想你知道如何对符号进行脱糖。

fmap = liftM and (<*>) = ap. Here are links to the source code for liftM and ap. I presume you know how to desugar do notation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文