Monad你我他

来源:互联网 发布:caffe 数据预处理 编辑:程序博客网 时间:2024/04/28 11:12

初识函数式编程的时候,Monad这个词就一直萦绕在我的耳边眼前和脑海中。这个在1991年由Eugenio Moggi从Category理论引进而来的概念,如同函数式编程中的许多其他概念一样有着深厚的数学背景。也许正是如此,Monad对于习惯了用传统命令式编程语言思考的人们可谓是一个难以理解的Monster。然而这个概念在越来越多的地方不断地出现,Haskell语言的官方站点上有一个关于Monad教程数量的趋势图,从某种程度应正了Monad在近几年中迅猛的发展势头。

Monad是什么

- Monad是一个构造因果关系的结构

    在传统命令式语言中计算是按照一条一条语句顺序的执行的。这种按照语句的顺序序列执行的逻辑是被语言本身抽象并隐藏的一个计算逻辑,即时间上的因果关系被语言当成默认能力隐藏了起来。当程序员们使用这种语言进行编程的时候会想当然的接受这种既定的因果关系,认为前一条语句执行后就是后一条语句,前一条产生的副作用将影响后续的语句。

    由于函数式语言接受的却是另一种世界观。在一个没有状态、没有副作用的真理世界中,时间上的因果关系其实并不是那么必要。但毕竟没有时间因果关系的世界和我们人类能够理解的世界相去甚远。为了弥补这个大洞,函数式编程引入了Monad。

- Monad是把副作用和因果关系关在大牢里的看守

  此处略过n万字...:)

- Monad是一个赋予计算顺序执行能力的工具

    Monad将函数式世界中的孤立的计算动作(真理描述)连接起来,让它们能够顺序的执行。Monad成为一种描述计算的顺序执行和操作这种执行顺序的工具。从某种意义上讲,Monad是程序语言中许多构造的元构造,Monad可以用来实现基本的顺序执行(如progn、begin)、goto、continuation、throw/catch等结构,它代表了这些计算逻辑的最通用的形式。

- Monad是一个把计算逻辑保存成值、操纵这些值的构造

    从这个方面理解Monad已经很容易了,这如同支持First class continuation的语言有能力把计算的逻辑当成一级对象保存起来一样,Monad也有能力把计算的逻辑保存起来留待后续的使用。

什么是Monad

- 作为抽象数据类型构造的Monad

    Monad是由一个类型构造(Type Constructor)和两个基本操作(Bind/Return)构成的构造。该类型构造将语言的一个基本类型转变成与之相对应的Monadic类型。Return操作则将语言基本类型的值转变成一个与该类型相对应的Monadic类型的值(这个操作其实并不改变值本身、而是值的类型拥有了Monadic的特性)。Bind操作则通过调用一个Monadic函数将一个Monardic类型的值转变为另外一个Monadic类型的值。可以看到通过Bind/Return这两个操作,就可以将Monadic函数顺序的串接起来形成一个处理Monardic类型输入值的管道,而管道中什么时候调用哪个Monadich函数由Monad本身的逻辑决定的。

- 形式化的Monad

    对于Monad应该符合下述的形式化描述(这里使用haskell里的符号表示>>=代表Bind操作, m是Monadic类型, x是基本类型):

    return x >>= f 等价于 f x

    m >>= return 等价于 m

    (m >>= f) >>= g 等价于 m >= ( λx.fx >= g )

- 程序语言中的Monad

    现如今能够看到Monad最多的地方也许就是在Haskell中,从I/O操作到各种抽象数据类型(Maybe、List等)都可以看到Monad用来实现这些语言元素的身影。更特别的是Haskell中的do运算符将Monad隐藏在这一切之后,给程序员一个传统命令式程序语言的界面(想当然的时间因果关系) --- 将函数式和传统命令式这两个持有不同的世界观的语言范式进行了一次大统一。

结语

    Monad作为一种强大的程序语言概念和构造,在现如今的函数式编程领域蓬勃发展。作为一种对函数式语言的弥补,使得状态、副作用、时间因果关系这类在函数式编程中较难处理的问题有了一种通用的解决方法,也从一个方面使得人们对传统命令式语言和函数式语言的关系有了更好的认识。

引用

http://en.wikipedia.org/wiki/Monad_(functional_programming)

http://www.haskell.org/haskellwiki/All_About_Monads

0 0
原创粉丝点击