Skip to content

还是P137页的7.2.5 monad vs monoid #6

Description

@boboyada

Monad 就是自函子范畴上的一个幺半群

但是举了这么些例子,怎么一点也看不出来 monad 与 monoid 的关系呢?倒是很明确 Monad 是个比较特殊的 Functor。

我们需要进一步的抽象才能解释这句话,首先,回顾前面 Monoid 的知识,比如那个 Sum 的 Monoid。

Sum.of(1).append(Sum.of(2)).append(Sum.of(0)) // => Sum.of(3)
这个 Monoid 很明显,它的二元操作是 append ,幺元是 Sum.of(0) ,范畴是 Sum 。 为了更明显我们可以降一个维度(范畴),把 Sum.of(1) 降成 1

(1 + 2 + 0)

但是 Monad 哪来的二元操作啊?一个 flat ,一个 fmap ,都是一元操作啊?

如果我们降一个维度, 到只有数字的维度上,

(1.2).3 = 1.(2.3)
二元操作 + 可以使得这个等式成立。 而幺元 0,又可以使得

0.2 = 2 = 2.0
在二元操作 + 上成立。

所以我们得到的 monoid 为 (数字集合,二元操作 + ,幺元 0)。

同样的,上升到函子的范畴上[fn:3],注意是自函子 范畴 上的幺半群,就代表的是函子范畴而不是函子实例是幺半群,所以以 Maybe 为例,就需要符合:

(Maybe.Maybe).Maybe = Maybe.(Maybe.Maybe)
能找到一个二元操作使得上式成立?而不是:

(Just.of(1).append(Just.of(2))).append(Just.of(3)) = Just.of(1).append(Just.of(2).append(Just.of(3)))
这个二元操作就是我们刚实现的 Just Monad 的 flat。我们很容易可以把 flat 代入到式子变换成以下格式,

flat(flat(Maybe.Maybe).Maybe) = flat(Maybe.flat(Maybe.Maybe))
其中的 . 是两个类型组合在一起。如同函数的组合是 f.g x= f(g(x)) ,在函子范畴上的组合就是 Maybe 类型的值,在一个 Maybe 类型的容器中:

Maybe.Maybe = Maybe[Maybe]
再代入一遍,就非常清晰结合律的等式是成立的了:

flat(flat(Maybe[Maybe])[Maybe]) = flat(Maybe[flat(Maybe[Maybe])])
大声念出来应该就是: flat 一个容器为 flat(Maybe[Maybe]) 类型,其值类型为 Maybe 得到的类型等于, flat 一个 Maybe 类型,其内值类型为 flat(Maybe[Maybe]) 所得到的类型。

听起来比较像绕口令,仔细看看等式就能理解了。另外一个 monoid 的法则是需要有一个幺元,满足:

?.Maybe = Maybe = Maybe.?
我们很容易能猜到把 Maybe 代入就是我的解,因此任何 Maybe 类型都是幺元:

flat(M[M]) = M = flat(M[M])
所以,flat 就像 moniod 里的 append 一样,但是它并不连接值或是容器,而是连接函子组合,让函子在不同范畴间变换

到这里,我可以告诉你现在的 Just 就是 Monad 了, 它是 Functor 的加强,把 fmap 的结果铺平(flat)。同时又是 Applicative 的加强, Applicative 让我们可以用一般函数作用到在容器中的值,而 Monad 让我们可以把一个容器中的值传入一个接收值的函数中,并返回同样的容器

上面的内容前半段能看懂,但从
###同样的,上升到函子的范畴上[fn:3],注意是自函子 范畴 上的幺半群,就代表的是函子范畴而不是函子实例是幺半群,所以以 Maybe 为例,就需要符合:

这段开始就很费解了。还请作者,对上面的文字推理再进行仔细思考,能否有好的表达?
我是几个月后,再来阅读时,还是堵住了。

另外,我觉得不是flat而是flatmap才是monad幺半群上的二元运算符?
拜托解疑

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions