如何定义Monad

更新时间:01-23 教程 由 心偿~ 分享

如何定义Monad?

Monad

A monad is just a monoid in the category of endofunctors

the category of endofunctors是自函子endofunctor的范畴(category),Monad是自函子范畴中的Monoid。

前面我们已经了解函子的映射原理,自函子可以理解为映射范畴C到另外一个范畴C。那么自函子的范畴是什么意思?是基于自函子的新范畴吗?经过查询此句原出处: Here it is in context,原文是:

All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor.

确实是基于范畴X的新范畴,这个新范畴看成是endofunctors on X。范畴X之上的范畴,这个新范畴的元素对象是自函子endofunctor,谈到范畴就要想到元素对象和态射,那么其态射是什么呢?

前面我们解释函子funtor工作原理时,有一句:"3.压平这两层集合,组合所有的结果",这个组合方式是一种自然变换natural transformation,属于新范畴的态射,因为态射有份两种:组合态射和元identitiy,自然变化就要对分别对X范畴中这两种进行转换。

所以,Monad工作原理包含两个部分:对原范畴组合成新的范畴,这个范畴对于Monad来说必须是幺半群Monoid,可以认为Monad是一系列自函子的组合,这种组合是一种转换,转换的结果是Monoid。

Monad有以下特征:

Monad是一种定义将函数(函子)组合起来的结构方式。(monoid是定义元素对象组合起来的结构方式。如果元素对象是特殊种类:函数(函子),那么它可能是Monad)这些组合的方法都是符合结合律的有一个特殊幺元,能够和任何元素组合,导致的结果是不改变这些元素。

关键对最后一点幺元讲解一下,以为什么需要Monad?一文中案例为说明,假设有两个数字a和b相加,这里a和b 可能为空,Java 代码如下:

int try_to_add_numbers( Integer a, Integer b ) { return a + b; }

如果a 和b非空,那么这个方法将会返回它们的总数,但是如果其中有一个是空的,我们会得到NullPointerException错误,调用客户端得到这个错误必须去处理它。而函数的定义是有一个输入类型和一个输出类型,现在又跑出第三种类型Exception,很显然Exception是和输入输出类型不属于同一个范畴,这就不符合封闭运算了。

那么我们使用一个幺元,比如Optional来封装结果,这样就能保证不抛出Exception,而是将Exception错误通过输出结构输出,这种结果分两种,要么是空,要么是有值,如果是有值,打开它就能获得真正的计算结果。我们使用Optional与结果值结合,但是不会改变这个结果值类型。具体可见: Java8中option实现Monad

总体来说:Monoid是元素对象的组合的范畴,如果这种元素对象是函数或函子(也可能是Pipe,这就复杂了去了 ),那么Monad是自函子的组合范畴,Monad也是一种特殊的Monoid子集。

如果你对大数据Hadoop等比较熟悉,map/reduce其实也是一个Monad。

最后我们用简单大白话(不精确有助于理解)翻译一下Monad的英文定义:A monad is just a monoid in the category of endofunctors,monad只不过也是一种特殊情况下的monoid,特殊在哪里呢?就是自己对自己进行转换的集合而已。

声明:关于《如何定义Monad》以上内容仅供参考,若您的权利被侵害,请联系13825271@qq.com
本文网址:http://www.25820.com/tutorial/14_2187856.html