`
cookoo
  • 浏览: 644541 次
  • 性别: Icon_minigender_1
  • 来自: Shanghai
社区版块
存档分类
最新评论

[fwd]什么是Monad?

    博客分类:
  • FP
阅读更多
发信人: faint (faint), 信区: FuncProgram
标  题: 什么是Monad(1): introduction
发信站: 水木社区 (Sun Oct  8 05:06:47 2006), 站内

在函数式编程里面,Monad是一个门槛。但是要解释“什么是monad”,这世界上没几个人
能一下讲清楚,因为涉及的背景知识太复杂。

介绍Monad可以被认为是一个"industry job":如果你能一下说清楚,就可以去当教授。

下面我说说我个人的从程序员角度的理解,目的不在于介绍monad的技术细节,而在于介
绍monad的背景和相关知识环境。

(基本概念:combinator/combinator programming/combinator language)

首先,函数式编程可以让我们方便的使用高阶函数(higher-order functions)写出很通用
的程序部件,比如map, fold, filter, \x->[x], 等等,这些函数组合性质和重用性都很
好,里面没有free variable,可以把这样的函数叫做"combinator"。

在程序里大量使用combinator就产生了一种编程风格,叫做"combinator programming"。
这种编程风格对于给定的问题定义几个combinator,然后拿这几个combinator当作一个“
语言”,把它们组合起来写程序。我们把这样由combinator构成的语言叫做"combinator
language"。

下面举几个combinator language例子:

例子1: 用map/fold/join/filter/unit这几个基本函数组合起来就可以写出很复杂的list
处理程序。

例子2: 函数式编程的状态经常要作为参数传递很麻烦, 就有人定义了所谓的"state
monad", 用几个基本的combinator部件来处理状态: return, bind, get, put

例子3: 一个很常见的应用就是所谓的"combinator parsing". 每一个基本的combinator
就是一个简单的parser, 只负责parse基本的语法单位, 比如我定义一个函数"word"来
parse一个词, 定义一个函数"number"来parse一个数字, 再定义一个函数"then"来组合各
种parser. 然后我就可以通过组合这些基本的函数来构造复杂的parser: "word then
number".

例子4: 最极端的例子是SK combinators,这两个函数组合起来跟图灵机等价,只用S和K
就可以编出一切程序.

(Generic combinator interfaces)

Combinator programming就像搭积木,用一些函数构造基本的积木块,再用一些组合性质
比较好的函数来连接各个模块,就像LEGO积木一样。人们编程经验很多以后,就总结出一
些基本的通用的设计模式,这些通用模式在很多combinator language中都适用。下面
要提到的Monad就是其中一个。

(Monad, monadic language)

Monad是一个通用的combinator interface。到底什么算是一个monad呢?如果我定义了一
个combinator language,里面有两个基本部件"return"和">>=",而且这两个部件满足以
下的组合性质,就可以说这个combinator language是一个monad:

   1. (return x) >>= f == f x
   2. m >>= return == m
   3. (m >>= f) >>= g == m >>= (\x -> f x >>= g)

这两个基本部件的意义其实很简单:return构造一个基本的"积木块",而(>>=)把各个积
木块顺序连接起来。如果一个combinator language里面有这样的基本结构,就可以说它
是一个monad,可以说这个language是一个monadic language。

由于monad有很好的组合性质,可以很容易的表达程序的控制结构,它成为很多
combinator language的设计方案。具体的例子很多,比如identity monad, maybe
monad, state monad, CPS monad,monadic parser combinators, 等等,都是经典的
monadic language。如果我想设计一个combinator language,首先就会想能不能设计
成一个monad。

(Monadic programming style)

如果我们设计的combinator language是一个monad,编出来的程序都会有一种特定的风格
:用return构造基本的积木块,用(>>=)组合各个模块。比如说,在Haskell的IO monad里
面我们可以写这么一段程序:
  return stdin   >>= (\h1 ->
  return stdout  >>= (\h2 ->
  hGetChar h1    >>= (\x ->
  hPutChar h2 x  >>= (\_ ->
  hPutChar h2 x ))))

实现的功能就是从stdin里面读入一个字符x,然后把它往stdout里面输出两次。可以看到
,通过使用return, >>=和匿名函数就可以实现复杂的variable binding。

(Monads in Haskell)

如果用其他的编程语言,上面的介绍就足够了。Haskell对Monad提供了更好的支持,可以
让基于Monad的编程更简单!具体有以下两点:

1. Type class。在Haskell里,可以把Monad定义成为一个type class,提供两个标准操
作:return和>>=。这样,不同的monad都可以重载这两个操作,让所有基于monad的程序
看上去都是相同的!

2. Do-syntax。既然type class可以让所有的monad程序都有相同的界面,只要让编译器
把这个界面化简一下,就相当于化简了所有monad界面。Haskell提供了一个"do-syntax"
,极大的简化了前一节提到的monadic programming style。比如说,前一节的程序可以
写为:
  do { let h1 = stdin
           h2 = stdout
       x <- hGetChar h1
       hPutChar h2 x
       hPutChar h2 x
     }

在编译的时候,这个使用do-syntax的程序会被翻译成前一节的基于return和>>=的程序。
现在看来,易读性已经和C/Java编程差不多了。。。
分享到:
评论
2 楼 bneliao 2009-08-14  

从应用及语言设计的组合子角度来讲monad,非常强大;

和t1的回albertLee:关于Category Theory 和Monad http://www.iteye.com/topic/147443?page=1 联系起来就很全面了
1 楼 coolspeed 2008-11-19  
很好很强大

相关推荐

    Fwd_ 计算机英语词汇Fwd_ 计算机英语词汇

    Fwd_ 计算机英语词汇Fwd_ 计算机英语词汇

    dpdk18版本下l2fwd自定义修改目的mac地址

    然后放入l2fwd文件夹中。 编译如下: # export RTE_SDK=/root/dpdk # export RTE_TARGET=build # make CC main.o LD l2fwd INSTALL-APP l2fwd INSTALL-MAP l2fwd.map 适配dpdk-17.11.1,命令通过新增-d指定...

    fwd:FWD-Web应用程序的便捷环境

    烟花网注意- fwd是死的,万岁 FWD项目已中止,转而使用我们的新解决方案 。 FWD为开发团队利用Docker容器进行本地开发提供了很多帮助。 kool现在以更大的功能和灵活性继续执行相同的任务,它的目标是使个人和团队...

    dpdk17版本下的l2fwd支持目的mac地址手动修改

    LD l2fwd INSTALL-APP l2fwd INSTALL-MAP l2fwd.map 适配dpdk-17.11.1,命令通过新增-d指定端口的dmac。 ./build/l2fwd -c 3 -n 2 -- -p 3 -d 11:11:11:11:11:11 -d 22:22:22:22:22:22 Port0的dmac为: 11:11:...

    FWD V101文件.zip_FWD UD_K60头文件

    "FWD V101文件.zip_FWD UD_K60头文件"这个标题暗示了这是一个与FWD(可能是某个软件框架或库)的版本V101相关的压缩包,其中包含了UD(用户定义)部分针对K60微控制器的头文件。在嵌入式系统开发中,头文件通常包含...

    fwd.zip_NOISE_fwd

    "fwd.zip_NOISE_fwd" 提供的功能文件是专门用于生成图像噪声的工具。这个功能可能对研究图像噪声特性、测试去噪算法或理解噪声对图像质量影响的研究人员非常有用。 噪声通常指的是图像中不期望存在的随机变化,可以...

    DPDKL2fwd代码走读报告(代码流程分析).pdf

    DPDKL2fwd代码走读报告(代码流程分析) DPDK(Data Plane Development Kit)是一种高性能的网络数据包处理平台,能够在通用x86服务器上实现高速网络数据包转发。该平台通过使用hugepage、uio、zero copy、cpu ...

    fwd_solve.doc

    《fwd_solve.doc》文档涉及了多个IT领域的知识点,主要集中在MATLAB编程、EIDORS库的使用、有限元方法(FEM)以及图像处理软件Avizo的运用。下面将逐一详细解析这些内容。 首先,`fwd_solve`是MATLAB中的一个函数,...

    Fwd: Extension-crx插件

    Fwd:文本,Fwd:链接,Fwd:图像,Fwd:捕获-保存您访问Fwd:Wiki的任何网站中的数据。 Google Meet出勤报告(具有自动允许/无依赖性),您可以将Meets组织到组中-添加| 编辑 删除以HTML文件格式下载报告或推送至...

    爱普生Epson TX820FWD 清零软件

    爱普生Epson TX820FWD是一款多功能一体机,集打印、扫描、复印和传真功能于一身,常被家庭和小型办公室用户所使用。然而,随着时间的推移,打印机内部的计数器可能会逐渐积累,导致打印质量下降或者出现错误提示。...

    海康IPC 网络摄像机DS-CD4026FWD SDK及DEMO

    海康威视(Hikvision)的IPC(网络摄像机)是安防监控领域的热门产品,其DS-CD4026FWD型号是一款备受青睐的网络摄像机。该产品不仅在市面上广泛应用,还为开发者提供了丰富的资源,以满足不同层次的二次开发需求,...

    Fwd.zip_zip

    【标题】"Fwd.zip_zip" 提到的文件是一个压缩包,它采用了 ZIP 文件格式,这是最常用的文件压缩格式之一。ZIP 格式允许用户将多个文件或文件夹打包成一个单一的文件,便于存储、传输和管理。"Fwd" 可能暗示这是一个...

    fwd.zip_Centroid

    首先,让我们深入理解什么是质心。质心是几何对象所有点的平均位置,可以视为物体在均匀密度下的平衡点。在二维空间中,如果有一组点集 (x1, y1), (x2, y2), ..., (xn, yn),质心 C(x, y) 可以通过以下公式计算: \...

    fwd.zip_zip

    标题 "fwd.zip_zip" 暗示我们正在处理一个包含其他文件的压缩包,它可能是一个项目或软件开发的组成部分。"rotatational project" 描述可能指的是这个项目与旋转相关的功能或特性,比如图形的旋转、物理模拟或者某种...

    fwd.rar_ppt评分

    【标题】"fwd.rar_ppt评分"是一个与计算机科学教育相关的项目,主要涉及的是一个用于计算机系PPT大赛的评分系统。这个系统可能被设计用来帮助评委们更有效地评估和打分参赛者的演示文稿,尽管其效率相对较低,但仍然...

    fwd.zip_The Dos

    【标题】"fwd.zip_The_Dos" 涉及到的是一个关于DOS操作系统以及可能与其相关的编程代码的知识点。DOS(Disk Operating System)是早期个人计算机上广泛使用的命令行操作系统,由微软公司开发。这个压缩包可能是包含...

    websocket_FWD.rar

    然而,根据提供的"websocket_FWD.rar"文件描述,这个项目并不依赖任何第三方库,而是直接使用了Win32 API来构建WebSocket服务端,这需要对网络编程有较深入的理解。 首先,我们需要了解Win32 API中的套接字(Socket...

    FWD FWD FWD-crx插件

    将社交媒体分享到正确的环境中。 当此扩展名侦听来自Facebook上经常共享的网站的链接时,该链接的标题将以FWD:FWD:FWD:为前缀。 支持语言:English

    TIME FWD-PAUSE-REVERSE.zip

    "TIME FWD-PAUSE-REVERSE.zip" 这个压缩包文件的名称暗示了它可能包含的内容与时间控制或时间操作相关,可能是某种软件、技术文档或者教程。"FWD"代表前进,"PAUSE"是暂停,"REVERSE"则指反向,这通常与多媒体播放器...

    dpdk l2fwd 示例代码改造支持arp 响应,支持ping 包

    dpdk l2fwd 示例代码改造支持arp 响应,支持ping 包

Global site tag (gtag.js) - Google Analytics