如何证明单子是一个函子和一个应用函子?
理论上,Monad 是函子和具体应用函子的子集,尽管 Haskell 的类型系统中没有指出这一点。
知道了,给定一个 monad 并基于 return
和 bind
,如何:
- 导出
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯,
fmap
只是(a -> b) ->发-> f b
,即我们想用纯函数转换一元动作的结果。使用 do 符号很容易编写:或者写成“raw”:
这可以作为
Control.Monad.liftM
。纯::a -> f a
当然是return
。(<*>) :: f (a -> b) ->发-> f b 有点棘手。我们有一个返回函数的操作,还有一个返回其参数的操作,并且我们希望有一个返回其结果的操作。再次用 do 表示法:
或者,脱糖:
Tada!这可以作为
Control.Monad.ap
,因此我们可以为任何 monadM
提供Functor
和Applicative
的完整实例> 如下:理想情况下,我们能够直接在 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:or, written "raw":
This is available as
Control.Monad.liftM
.pure :: a -> f a
is of coursereturn
.(<*>) :: 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:Or, desugared:
Tada! This is available as
Control.Monad.ap
, so we can give a complete instance ofFunctor
andApplicative
for any monadM
as follows: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 makingApplicative
a superclass ofMonad
, as it'll ensure it doesn't break any existing code. On the other hand, this means that the boilerplate involved in definingFunctor
andApplicative
instances for a givenMonad
is minimal, so it's easy to be a "good citizen" (and such instances should be defined for any monad).fmap = liftM
和(<*>) = ap
。以下是 源代码的链接liftM 和 ap。我想你知道如何对符号进行脱糖。fmap = liftM
and(<*>) = ap
. Here are links to the source code for liftM and ap. I presume you know how to desugar do notation.