<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_除却巫山不是云</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/20537/rss</id><updated>2012-04-12T05:04:10Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/20537/rss"/><entry><id>http://www.cnblogs.com/darkluck99/archive/2012/03/20/2407456.html</id><title type="text">Clojure程序员的Monad之旅（Part 4）</title><summary type="text">Clojure程序员的Monad之旅（Part 4）Monad在函数式编程中常常跟Haskell联系在一起。在Haskell中，他们在I/O等很多应用中扮演了核心角色。目前多数对monad的介绍都是为Haskell程序员编写的，尽管如此，monad可以在任何一种函数语言中使用，甚至某些语言跟Haskell想去甚远。这里，我要使用Clojure来解释monad的概念，Clojure是一种拥有强大函数编程支持的，时髦的lisp方言。Part4包含很多有趣的概率问题，赶紧来看啦！</summary><published>2012-03-20T05:32:00Z</published><updated>2012-03-20T05:32:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2012/03/20/2407456.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2012/03/20/2407456.html"/><content type="html">&lt;font color="#333333" face="Tahoma" style="background-color: #ffffff; text-align: left; "&gt;&lt;span style="line-height: 30px; font-size: 10pt; "&gt;翻译自&lt;/span&gt;&lt;/font&gt;&lt;span style="background-color: #ffffff; text-align: left; "&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://onclojure.com/2009/04/24/a-monad-tutorial-for-clojure-programmers-part-4/" title=" A Monad Tutorial For Clojure Programmers (Part 4)"&gt;A Monad Tutorial For Clojure Programmers (Part 4)&lt;/a&gt;&lt;div style="border:none;border-bottom:solid #6699CC 1.0pt;padding:0in 0in 0in 0in;background: white"&gt;&lt;p&gt;&lt;font color="#333333" face="Tahoma" size="2"&gt;&lt;span style="line-height: 30px;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;font face="Tahoma, sans-serif"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;在本次旅程的最后一节，我将会介绍&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;。我只介绍其中的一种，然后我会介绍&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;probability monad &lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;以及&lt;/span&gt; &lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;如何使用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;来扩展它。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;简单来说，&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;是一个函数，参数是一个&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;，返回值也是一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。返回的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是通过给传入的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;增加一些功能而产生的变形。这些增加的功能，是由&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;定义的。许多我前面提到的普通的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，都有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad transformer &lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;模拟，可以增加功能，使他们成为其它的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;考虑一下我们前面讨论过的&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;用来对可能失败的运行返回有效的值&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;。&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence monad &lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;用来对运算返回多值的结果，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值组成的序列。把这个两个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;组合成一个新的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，可以有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;种形式：&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;）返回多值结果，值&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;表示运算失败；&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;）或者返回多值结果，或者在失败的情况下返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。形式&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;）是比较有用的，对于形式&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;）来说实用价值不大，运算失败只要返回空序列的方式更简便。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;那么，我们用什么办法把&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;组合起来，以便用现有的功能来实现我们所需的功能呢？很遗憾，这是做不到的。但是，我们可以保持一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;不变，而把另一个改写成一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。使用这个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;来处理&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;（或其他的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;）来获得我们想要的结果。为了实现需要组合，我们就可以把&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;转换成一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt; monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，然后把他应用到&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;首先，看一下这两个&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;的定义：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;(defmonad&amp;nbsp;maybe-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[m-zero&amp;nbsp;&amp;nbsp;&amp;nbsp;nil&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-result&amp;nbsp;(fn&amp;nbsp;[v]&amp;nbsp;v)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-bind&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[mv&amp;nbsp;f]&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(nil?&amp;nbsp;mv)&amp;nbsp;nil&amp;nbsp;(f&amp;nbsp;mv)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-plus&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[&amp;amp;&amp;nbsp;mvs]&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(first&amp;nbsp;(drop-&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;&amp;nbsp;nil?&amp;nbsp;mvs)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;])&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;(defmonad&amp;nbsp;sequence-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[m-result&amp;nbsp;(fn&amp;nbsp;[v]&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(list&amp;nbsp;v))&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-bind&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[mv&amp;nbsp;f]&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(apply&amp;nbsp;concat&amp;nbsp;(map&amp;nbsp;f&amp;nbsp;mv)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-zero&amp;nbsp;&amp;nbsp;&amp;nbsp;(list)&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-plus&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[&amp;amp;&amp;nbsp;mvs]&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(apply&amp;nbsp;concat&amp;nbsp;mvs))&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;])&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;然后看一下&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe monad transformer&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的定义：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;maybe-t&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[m]&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(monad&amp;nbsp;[m-result&amp;nbsp;(with-monad&amp;nbsp;m&amp;nbsp;m-result)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-bind&amp;nbsp;&amp;nbsp;&amp;nbsp;(with-monad&amp;nbsp;m&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[mv&amp;nbsp;f]&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-bind&amp;nbsp;mv&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[x]&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(nil?&amp;nbsp;x)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-result&amp;nbsp;nil)&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(f&amp;nbsp;x))))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-zero&amp;nbsp;&amp;nbsp;&amp;nbsp;(with-monad&amp;nbsp;m&amp;nbsp;m-zero)&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-plus&amp;nbsp;&amp;nbsp;&amp;nbsp;(with-monad&amp;nbsp;m&amp;nbsp;m-plus)&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;在&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;clojure.contrib.monads&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;库中真正的定义，比这个要复杂一些，我稍后会解释，但我们现在的版本，已经够不错了。组合后的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;这样定义&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(def&amp;nbsp;maybe-&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;-sequence-m&amp;nbsp;(maybe-t&amp;nbsp;sequence-m))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;直接调用这个函数，返回一个&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;。让我们看看&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的作用，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;identity&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，因此&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数，就是我们需要的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。事实正是如此，（&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;with-monad&amp;nbsp; m m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;）返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数。同样的结构，我们在&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-plus&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;中也看到了，这说明，我们要修改的仅仅是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;部分。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;组合后的&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;抵用了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数，但是修改了参数，使用一个函数来表示其余的运算。在调用之前，首先检查参数是否为&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。如果为&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，就调用原先的函数，这样组合后的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;同基础&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;一样，不需要计算，返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。尽管如此，我们不能只是返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，我们必须返回一个有效的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值（在我们的例子中是返回序列中的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;元素）。因此，我们把&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;传回给基础&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-result&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，由它来把&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;包装到最终所需的结果中。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;让我们看看实际的情况：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(domonad&amp;nbsp;maybe-&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;-sequence-m&lt;br /&gt;&amp;nbsp;&amp;nbsp;[x&amp;nbsp;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;nil&amp;nbsp;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;[&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&amp;nbsp;nil&amp;nbsp;&lt;span style="color: #800080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;40&lt;/span&gt;]]&lt;br /&gt;&amp;nbsp;&amp;nbsp;(+&amp;nbsp;x&amp;nbsp;y))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;输出结果是：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; color: red; "&gt;(11 nil 31 41 12 nil 32 42 nil 14 nil 34 44)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;正如我们期望的，所有的非&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;值计算后都正常，但是第一眼看到这个结果我们有些惊讶，为什么是&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;4&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;而不是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;8&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个呢（每个输入序列中的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和分别另外一个序列的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;4&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个元素相加）？&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;为了理解这个原因，我们来看一下&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;中的&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;函数，在顶层，使用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;[1 2 nil 4]&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;作为&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值来运算。他把这个结构传给&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数，这个匿名函数总共调用了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;4&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;次（每个元素&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;次）。对于其中&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个非&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的值只是普通的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;+&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;运算；对于&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值，结果直接返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，不进行运算。这样，第一个输入&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;vector&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;中的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;元素，在结果中产生了一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值，剩余的运算部分只执行了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;次。这&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;次运算，每次又产生了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个有效的值和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，这样从第二个输入&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;vector&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，我们就得到了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3 x 3 = 9&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个有效值，和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3 x 1 = 3&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，加上从第一个输入&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;vector&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;得到的一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;ni&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，一共是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;9&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个值和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;4&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;用什么办法可以获得全部的&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt; 4 x 4&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;共计&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;16&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个运算值吗？当然，但是不能使用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。你只能分别使用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;来计算：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(with-monad&amp;nbsp;maybe-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(def&amp;nbsp;maybe-+&amp;nbsp;(m-lift&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;+)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;(domonad&amp;nbsp;sequence-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[x&amp;nbsp;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;nil&amp;nbsp;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;[&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&amp;nbsp;nil&amp;nbsp;&lt;span style="color: #800080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;40&lt;/span&gt;]]&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(maybe-+&amp;nbsp;x&amp;nbsp;y))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;如果你使用&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;，你总是会被短路逻辑影响：一旦有一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，就返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，并不继续进行剩余的计算。大多数情况下，这符合我们的需要。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的组合并没有多少实用价值，因为一个更简单有效的方法是在计算前把非有效的参数从输入序列中移出。但是这个例子很简单，又能很好的解释原理。现在我们准备挑战一个更有实际意义的例子：使用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;probability distribution monad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;probability distribution monad&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;用来处理有限概率分布，比如，在一个有限元素组成的集合里有非&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;0&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;值的概率。这个概率用一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;map&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;来表示，分别是值和它们出现的记录。有限分布相关的函数和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;在&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #993300; "&gt;clojure.contrib.probabilities.finite-distributions&lt;/span&gt;&lt;span style="font-size: 9pt; "&gt;库中。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;巫云@：&lt;br /&gt;由于目前clojure.contrib.probabilities.finite-distributions的代码跟clojure 1.3.0以上版本不兼容，这里我是使用clojure 1.2.0进行测试的。&lt;br /&gt;使用leiningen的同学可以参考我的文章&lt;a title="《64位window7下配置Clojure+Emacs开发环境》" href="http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html"&gt;《64位window7下配置Clojure+Emacs开发环境》&lt;/a&gt;进行配置。关于出现这个问题的原因可参照这篇&lt;a title="文章" href="http://blog.japila.pl/2011/03/cant-dynamically-bind-non-dynamic-var-in-clojure-1-3/"&gt;文章&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;有限分布的一个简单例子：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(use&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;clojure.contrib.probabilities.finite-distributions)&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;(def&amp;nbsp;die&amp;nbsp;(uniform&amp;nbsp;#{&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;}))&lt;br /&gt;(prob&amp;nbsp;odd?&amp;nbsp;die)&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;输出&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;1/2&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;，这是扔骰子点数出现偶数的概率。&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;die&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的值，是扔骰子使出现的点数及其概率的分布情况：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; color: red; "&gt;{6 1/6, 5 1/6, 4 1/6, 3 1/6, 2 1/6, 1 1/6}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;假设我们扔&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;次骰子，然后观察两次点数的和。他们的概率分布是怎样的呢？&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(domonad&amp;nbsp;dist-m&lt;br /&gt;&amp;nbsp;&amp;nbsp;[d1&amp;nbsp;die&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;d2&amp;nbsp;die]&lt;br /&gt;&amp;nbsp;&amp;nbsp;(+&amp;nbsp;d1&amp;nbsp;d2))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;结果是：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; color: red; "&gt;{2 1/36, 3 1/18, 4 1/12, 5 1/9, 6 5/36, 7 1/6, 8 5/36, 9 1/9, 10 1/12, 11 1/18, 12 1/36}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;我们来看一下&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;domonad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;块的内容：第一次的分布&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;die&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;绑定到&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;d1&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，第二次的分布&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;die&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;绑定到&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;d2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，然后计算&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;d1+d2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的分布。这个例子很简单，概括来说，每次分布情况取决于上一次分布情况，这样就创建了变量的联合分布。这个方法被称为&amp;#8220;原始取样&amp;#8221;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;这个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;使用组合概率的基本原则：如果事件&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;A&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;发生的概率是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;p&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，事件&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;B&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;发生的概率是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;q&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，并且二者是相互独立的（至少互不影响），那么&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;A&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;B&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;同事发生的概率为&lt;/span&gt; &lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;p x q&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。看&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的定义：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defmonad&amp;nbsp;dist-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[m-result&amp;nbsp;(fn&amp;nbsp;[v]&amp;nbsp;{v&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;})&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-bind&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[mv&amp;nbsp;f]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(letfn&amp;nbsp;[(add-prob&amp;nbsp;[dist&amp;nbsp;[x&amp;nbsp;p]]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(assoc&amp;nbsp;dist&amp;nbsp;x&amp;nbsp;(+&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&amp;nbsp;dist&amp;nbsp;x&amp;nbsp;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;)&amp;nbsp;p)))]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(reduce&amp;nbsp;add-prob&amp;nbsp;{}&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;for&lt;/span&gt;&amp;nbsp;[[x&amp;nbsp;p]&amp;nbsp;mv&amp;nbsp;&amp;nbsp;[y&amp;nbsp;q]&amp;nbsp;(f&amp;nbsp;x)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[y&amp;nbsp;(*&amp;nbsp;q&amp;nbsp;p)]))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;])&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;像往常一样，&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;m-bind&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;中发生了有趣的事情。第一个参数&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;mv&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;是一个&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;map&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;，里面存放概率分布情况；第二个参数&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;f&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;是一个函数，代表剩余的运算，对于每个&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;for&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;里面的概率值，调用这个函数。&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;for&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;表达式同时遍历输入分布里的概率和（&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;f x&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;）返回的概率分布里的概率，通过乘法操作计算联合概率，并把结果输出到输出分布。通过对辅助函数&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;add-prob&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;上使用&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;reduce&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;来完成运算。&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;add-prob&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;的检查当前的&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;map&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;的值是否存在，如果存在，更新概率为&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;add&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;后的新值。这是必须的，因为在（&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;f x&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;）的取样过程中，同一个值如果对应不同的&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;x&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;，则可能被包含多次。（巫云&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;@&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;：比如&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt; 1+ 2 = 3&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;，&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt; 2 + 1 = 3&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;，&lt;/span&gt;&lt;span style="font-size:9.0pt;line-height:115%;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;3&lt;/span&gt;&lt;span lang="ZH-CN" style="font-size:9.0pt;line-height:115%;font-family:宋体;mso-ascii-font-family:Verdana;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Verdana;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;color:#333333;mso-ansi-language:EN-US;mso-fareast-language:ZH-CN;mso-bidi-language:AR-SA"&gt;可能出现多次）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;（巫云@：比如 1+ 2 = 3，2 + 1 = 3&amp;lt;，3可能出现多次）&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;再看一个更有趣的例子，著名的&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;Monty Hall&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;问题&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;。在一个电视现场游戏中，玩家面对&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; "&gt;扇门，其中只有一个门后面有奖品。如果玩家选择了正确的门就能得到奖品。&lt;/span&gt;&lt;span style="font-size: 9pt; "&gt;说到这里，这个问题就可以简化为，获奖概率是&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; "&gt;1/3&lt;/span&gt;&lt;span style="font-size: 9pt; "&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;（巫云@：这个游戏也是来自一款电视节目，貌似跟砸蛋很像啊~）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;但是这里有个小插曲，在玩家做出选择之后，主持人打开剩余&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;扇门中的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;扇，这扇门后面是没有奖品的。然后主持人问玩家是否变更原先的选择。这真是个不错策略，是吧。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;为了更好的定义这个问题，我们假设主持人是知道奖品位置的，因此他不会开打有奖品的门。然后我们开始编程：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(def&amp;nbsp;doors&amp;nbsp;#{:A&amp;nbsp;:B&amp;nbsp;:C})&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;(domonad&amp;nbsp;dist-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[prize&amp;nbsp;&amp;nbsp;(uniform&amp;nbsp;doors)&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;choice&amp;nbsp;(uniform&amp;nbsp;doors)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(=&amp;nbsp;choice&amp;nbsp;prize)&amp;nbsp;:win&amp;nbsp;:loose))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;一步步的看，首先，我们从&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;A&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;B&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;C&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;三个门中选择一个作为作为放奖品的门，这代表玩家开始游戏前的前奏。然后玩家开始选择。最后我们公布结果，输出&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:win&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;或者&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:loose&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。很明显概率情况毫无异议，&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #ff0000; "&gt;{:win 1/3, :loose 2/3}&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;这覆盖了玩家不听取主持人建议的情况，如果他接受了主持人的建议，情况变得更加复杂：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(domonad&amp;nbsp;dist-m&lt;br /&gt;&amp;nbsp;&amp;nbsp;[prize&amp;nbsp;&amp;nbsp;(uniform&amp;nbsp;doors)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;choice&amp;nbsp;(uniform&amp;nbsp;doors)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;opened&amp;nbsp;(uniform&amp;nbsp;(disj&amp;nbsp;doors&amp;nbsp;prize&amp;nbsp;choice))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;choice&amp;nbsp;(uniform&amp;nbsp;(disj&amp;nbsp;doors&amp;nbsp;opened&amp;nbsp;choice))]&lt;br /&gt;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(=&amp;nbsp;choice&amp;nbsp;prize)&amp;nbsp;:win&amp;nbsp;:loose))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;第&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;步变得最为有趣：主持人打开一扇未被选择的，并且没有奖品的门。我们的模型用移除奖品门和被选择门来体现这一步骤，从结果集合中我们可以看到，结果中包含&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个或&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个元素，取决于被选择门和奖品门。然后玩家改变他的选择，转而选择留下的那个门。在标准的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个门游戏中，这个可选集合里只有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个门，但是上面的代码适合更多门的情况。大家可以自己尝试一下。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;执行的结果是&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #ff0000; "&gt;{:loose 1/3, :win 2/3}&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，说明改变自己的选择是一个更佳的策略。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;回到&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;，在有限分布库中定义了一个&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(def&amp;nbsp;cond-dist-m&amp;nbsp;(maybe-t&amp;nbsp;dist-m))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;这使&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;成为一个特殊值，表达那些我们不想考虑的可能情况。使用&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;，你能猜到在分布联合时&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是如何传递的：对于任何的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值，任何对它有潜在依赖的分布都不被计算，并且&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;值的概率被整个传递给输出结果中&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;ni&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的概括。但是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是如何进入到分布中的呢？并且这样做有什么好处呢？&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;l&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;考虑最后这个问题，分布中引入&lt;/span&gt;&lt;span style="font-size: 9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;的作用，是为了消除特定的值。一旦得到最终的分布情况，&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;值会被移除，并且剩余的分布不会产生异常，他们的概率只和为&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;。移除&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;以及消除异常的操作通过函数&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;normalize-cond&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;来完成。&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;cond-dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是一个计算条件概率的经典方法，并常常用于辅助贝叶斯推理（各种数据分析中使用的重要技术）。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;第一个练习，我们根据输入的分布和断言，来计算一个简单的条件概率。输出的分布只包含符合断言的值，但是概率分布的结果会被正常化：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;cond-prob&amp;nbsp;[pred&amp;nbsp;dist]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(normalize-cond&amp;nbsp;(domonad&amp;nbsp;cond-dist-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[v&amp;nbsp;dist&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:when&amp;nbsp;(pred&amp;nbsp;v)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;关键的代码是&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;:when&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;语句，正如我在第一和第二节提到的那样。&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;domonad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;表达式展开为：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(m-bind&amp;nbsp;dist&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[v]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(pred&amp;nbsp;v)&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-result&amp;nbsp;v)&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m-zero)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;如果你前面仔细留心，你可能要抱怨：使用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;cond-dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;应该不需要&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。但是，我前面说过，这里使用的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是一个简化版，真正的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;要检查参数&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是否有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，如果没有，用自己的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;(with-monad m (m-result nil))&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;来代替它。因此&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;cond-dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;{nil 1}, &lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;这个分布的唯一值就是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;domonad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;在这里起的唯一作用就是保持所有符合断言的值的概率保持不变。调用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;normalize-cond&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;去除&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，并用有效值的概率重建分布结果：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;(cond-prob odd? die)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; color: #ff0000; "&gt;-&amp;gt; {5 1/3, 3 1/3, 1 1/3}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;cond-dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;在解决贝叶斯推理时变得太有趣了。贝叶斯推理是一项描绘不完全观察推论的技术。有广阔的应用领域，从垃圾邮件过滤到天气预报。关于这个推论的数学基础可以查看&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;&lt;a href="http://en.wikipedia.org/wiki/Bayesian_inference" title="Wiki"&gt;wiki&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;这里我们要讨论一个很简单的推理问题和它在&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;Clojure&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;中的解决方案。假设你有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个骰子，第一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;6&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个面，第二个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;8&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个面，第三个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;12&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个面。一个人拿起一个骰子，投几次，然后告诉点数，但并不告诉我们用的是哪个骰子。根据现象，我们来计算每个骰子被选中的可能性。我们定义一个函数，返回拥有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;n&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个面的骰子的点数分布概率：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;die-n&amp;nbsp;[n]&amp;nbsp;(uniform&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;(inc&amp;nbsp;n))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;接下来，我们参考贝叶斯推理的核心知识。中心要素是考虑使用过的骰子扔出的点数的分布情况。我们需要每个骰子的概率分布：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(def&amp;nbsp;dice&amp;nbsp;{:six&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(die-n&amp;nbsp;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:eight&amp;nbsp;&amp;nbsp;&amp;nbsp;(die-n&amp;nbsp;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&amp;nbsp;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:twelve&amp;nbsp;&amp;nbsp;(die-n&amp;nbsp;&lt;span style="color: #800080;"&gt;12&lt;/span&gt;)})&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;另外一个中心要素是体现选择骰子选取优先顺序的分布概率。我们对此没有定义，每个骰子被使用的概率是完全一样的：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(def&amp;nbsp;prior&amp;nbsp;(uniform&amp;nbsp;(keys&amp;nbsp;dice)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;现在我们开始写推理函数。参数是选取的优先分布和观察的点数，返回一个综合了优先顺序和点数信息的归纳分布。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;add-observation&amp;nbsp;[prior&amp;nbsp;observation]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(normalize-cond&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(domonad&amp;nbsp;cond-dist-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[die&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prior&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;number&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&amp;nbsp;dice&amp;nbsp;die)&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:when&amp;nbsp;&amp;nbsp;(=&amp;nbsp;number&amp;nbsp;observation)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;die)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;看一下&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;domonad&lt;/span&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;，第一步根据优先级选取骰子；第二步，扔骰子获得一个点数；第三步，去除不在观察范围内的点数；最后返回&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;die&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的分布。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;建议把这个函数和贝叶斯定理进行比较。贝叶斯定理&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;P(H|E) = P(E|H) P(H) / P(E),&lt;/span&gt; &lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;其中&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;H&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;表示假设（&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;hypothesis&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，假设选择了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;X&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;骰子），&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;E&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;表示事实（&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;evidence&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，观察的现象是扔出的点数&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;N&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;）。&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;P(H)&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;是优先序列。这个公式必须在确定的值&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;E&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;上使用。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt;font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;domonad&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;第一行实现了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;P(H)&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，第二行实现了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;P(E|H)&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。这两行合在一起就是一个我们前面提到的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;P(E, H)&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;原始取样。&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:when&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;代表了观察现象；我们希望把贝叶斯定理使用到确定的值&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;E&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。一旦&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;E&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;确定了，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;P(E)&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;就是一个数字。最后&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;"&gt;normalize-cond&lt;/span&gt;&lt;span style="font-size:10.0pt;Courier New&amp;quot;;Courier New&amp;quot;;Courier New&amp;quot;"&gt;对它&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;进行正常化。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;让我们看一下在观察到&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;的情况下是什么结果：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(add-observation&amp;nbsp;prior&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;)&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; color: #ff0000; "&gt;-&amp;gt; {:twelve 2/9, :eight 1/3, :six 4/9}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;我们看到概率最高的的&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;:six&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;，其次是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:eight&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，最小的是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:twelve&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。这是因为，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;在&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个骰子上都存在，但是它在&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;6&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个面的骰子上，出现概率是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1/6&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;，在&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;8&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;面和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;12&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;面上的概率自然是&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1/8&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;1/12&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。这次观察的结果倾向于面较少的骰子。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;如果我们观察&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;次，我们可以重复调用&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;add-observation&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(-&amp;gt;&amp;nbsp;prior&amp;nbsp;(add-observation&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-observation&amp;nbsp;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-observation&amp;nbsp;&lt;span style="color: #800080;"&gt;7&lt;/span&gt;))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; color: red; "&gt;-&amp;gt; {:twelve 8/35, :eight 27/35}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;现在我们看到&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;; color:#333333"&gt;:six&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family: 宋体;Times New Roman&amp;quot;; color:#333333"&gt;消失了，因为观察到了&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;7&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;；接下来，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:eight&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;比&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:twelve&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;得到了更多的青睐，也进一步验证了面较少的骰子，被选中的可能性较大。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;这个定理在解决垃圾邮件过滤问题时的情况类似。在这个情况下，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;个骰子被替换成选项&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:spam&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:no-spam&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。对每一个选项，我们通过分析邮件正文得到一个词的分布概率。&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;add-observation&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;除了变量名函数完全相同。当我们对每一个想要分析的词进行评估的时候，可以根据数据库存储的对它的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:spam&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;:no-spam&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的选择次数，算出一个优先顺序分布。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#333333" face="Verdana, sans-serif"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:9.0pt; Times New Roman&amp;quot;;color:#333333"&gt;在介绍&lt;/span&gt;&lt;span style="font-size:9.0pt; font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad transformers&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;内容的最后，我来解释一下&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;问题。正如你知道的，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;mabye-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;有一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;函数&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;(nil)&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和一个&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-plus&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的定义，它们在被&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;使用时是可以被移除的。这就是为什么看到&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;cond-dist-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;要那么做的原因。尽管如此，就像&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;sequence-m&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;一样，基础的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;可以拥有自己的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-plus&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;。那么组合的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;应该定义那些内容呢？只有&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的作者才能做出决定，所以&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;在这里有一个可选参数（看相关文档）。我们唯一可以明确的一点是，当一个基础的&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;不包含&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-zero&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;和&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;m-plus&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;的时候，&lt;/span&gt;&lt;span style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;Times New Roman&amp;quot;;color:#333333"&gt;maybe-t&lt;/span&gt;&lt;span style="font-size:9.0pt;Times New Roman&amp;quot;;color:#333333"&gt;肯定不会对它造成影响。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;巫云@：&lt;br /&gt;最后，&lt;strong&gt;偶&lt;/strong&gt;再扼要总结一下这个系列讲到的monad的基本知识点：&lt;br /&gt;1. monad是一种函数式编程常用的方法，把依赖前一步运算结果的多步运算组成一个运算。&lt;br /&gt;2. monad定义中包括m-result，m-bind，m-zero和m-plus。其中m-result和m-bind是必须定义的：&lt;br /&gt;m-result把每一个运算的结果包装后传递给m-bind剩余的执行步骤；m-bind根据绑定表达式把多步操作组成一个链。&lt;br /&gt;3. domonad宏可以简化代码，它展开后成为一个(with monad ...)的block，包含m-bind，m-result等组成的运算结构。&lt;br /&gt;4. 通过monad transformer可以把一个monad进行功能修改，变成另一个monad。&lt;br /&gt;5. 一些常用的monad：identity-m, maybe-m, sequence-m, state-m, dist-m等。&lt;br /&gt;&lt;br /&gt;好了，这个系列的4篇文章翻译完了。虽然内容包含许多函数编程和数学知识，不是很容易理解，但是如果大家仔细读过，也一定会有所收获的，感谢大家的支持！&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/darkluck99/aggbug/2407456.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/20/2407456.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/darkluck99/archive/2012/03/18/2404934.html</id><title type="text">Clojure程序员的Monad之旅（Part 3）</title><summary type="text">Clojure程序员的Monad之旅（Part 3）Monad在函数式编程中常常跟Haskell联系在一起。在Haskell中，他们在I/O等很多应用中扮演了核心角色。目前多数对monad的介绍都是为Haskell程序员编写的，尽管如此，monad可以在任何一种函数语言中使用，甚至某些语言跟Haskell想去甚远。这里，我要使用Clojure来解释monad的概念，Clojure是一种拥有强大函数编程支持的，时髦的lisp方言。</summary><published>2012-03-18T10:44:00Z</published><updated>2012-03-18T10:44:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2012/03/18/2404934.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2012/03/18/2404934.html"/><content type="html">&lt;div style="border:none;border-bottom:solid #6699CC 1.0pt;padding:0cm 0cm 0cm 0cm;background: white"&gt;&lt;p align="left" style="margin-bottom:6.8pt;text-align:left;background:white;border:none;padding:0cm;"&gt;&lt;font color="#333333" face="Tahoma"&gt;&lt;span style="line-height: 30px; font-size: 10pt; "&gt;翻译自&lt;/span&gt;&lt;/font&gt;&amp;nbsp;&lt;a href="http://onclojure.com/2009/03/23/a-monad-tutorial-for-clojure-programmers-part-3/" title="A Monad Tutorial For Clojure Programmers (Part 3)"&gt;&lt;span style="font-size: 10pt; "&gt;A Monad Tutorial For Clojure Programmers (Part 3)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p align="left" style="text-align:left;background:white"&gt;&lt;font color="#333333" face="Tahoma" size="2"&gt;&lt;span style="line-height: 19px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;&amp;nbsp; &amp;nbsp;在开始&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;高级话题之前，我们简单回顾一下&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;的定义（参考&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html" title="Part 1"&gt;Part 1&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;和&lt;a title="Part 2" href="http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html"&gt;Part 2&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;）：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="margin-top:6.8pt;margin-right:0cm; margin-bottom:6.8pt;margin-left:36.0pt;text-align:left;text-indent:-18.0pt; line-height:15.6pt;background:white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;1.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #333333; font-family: 宋体; font-size: 8pt; background-color: white; line-height: 15.6pt; "&gt;一种数据结构，表现运算的结果，或者运算本身。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="margin-top:6.8pt;margin-right:0cm; margin-bottom:6.8pt;margin-left:36.0pt;text-align:left;text-indent:-18.0pt; line-height:15.6pt;background:white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;2.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;使用&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;m-result&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;函数，把一般的值，转换成等价的&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;monad&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;数据结构。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="margin-top:6.8pt;margin-right:0cm; margin-bottom:6.8pt;margin-left:36.0pt;text-align:left;text-indent:-18.0pt; line-height:15.6pt;background:white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;3.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;使用&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;m-bind&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;函数，绑定一个使用&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;monad&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;数据结构表示的运算的值到一个名称（使用接受一个参数的函数），使这个值在接下来的运算中可用。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;以&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;为例，数据结构为&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;，表示最终结果非唯一的运算；&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;list&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;函数，把每次运算结果转换成一个序列，序列的元素是运算的每个值转成的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;list&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;；&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;函数继续对序列进行处理，并把结果移出&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;list&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;嵌套。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;以上&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;3&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;个要素定义了一个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，有些&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;除了这些必要条件外，还增加了&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;2&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;个额外的定义，以实现特殊功能。这两个函数就是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;和&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;。&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;代表一个特殊的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;值，表示当一个运算没有返回值时的返回结果。例如：&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;中的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，通常代表了计算过程失败。另一个例子是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;中的空序列。&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;identity monad &lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;则是不包括&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的例子。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#84939f" face="宋体"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;函数把多个计算的结果合并成一个。对&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;来说，就是把多个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;连接成一个；对&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;来说，就是返回参数列表中第一个不是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;的参数。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;和&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;需满足的条件：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;span style="font-size: 12pt; font-family: 宋体; color: #008000; "&gt;(= (m-plus m-zero monadic-expression)&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;span style="font-size: 12pt; font-family: 宋体; color: #008000; "&gt;&amp;nbsp;&amp;nbsp; (m-plus monadic-expression m-zero)&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;span style="font-size: 12pt; font-family: 宋体; color: #008000; "&gt;&amp;nbsp;&amp;nbsp; monadic-expression)&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;一句话，就是组合&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;m-zero&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;和任意的&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;monad&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;表达式，必须返回等价的值。可以从&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;maybe&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;和&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;sequence&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;中验证这一点。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;中使用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的好处之一就是可以使用条件分支。在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;Part1&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;中，我们提及了&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;:when&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;表达式，现在我们就来讨论：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;for&lt;/span&gt;&amp;nbsp;[a&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:when&amp;nbsp;(odd?&amp;nbsp;a)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(*&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;a))&lt;/div&gt;&lt;/div&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;使用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;domonad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;来表示：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(domonad&amp;nbsp;sequence&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[a&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:when&amp;nbsp;(odd?&amp;nbsp;a)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(*&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;a))&lt;/div&gt;&lt;/div&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;domonad&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;宏把&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;let&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;形式的语法，转换成&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;和&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的组合式，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;a (range 5) &lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;等价于&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(m-bind&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&amp;nbsp;(fn&amp;nbsp;[a]&amp;nbsp;remaining-steps))&lt;/div&gt;&lt;/div&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;在&lt;/span&gt;&lt;span style="font-size:12.0pt;color:#333333;"&gt;remaining-steps&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;中&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;:when&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;语句被特殊处理&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;predicate&amp;nbsp;remaining-steps&amp;nbsp;m-zero)&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;这个例子完全展开后就成为&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(m-bind&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&amp;nbsp;(fn&amp;nbsp;[a]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(odd?&amp;nbsp;a)&amp;nbsp;(m-result&amp;nbsp;(*&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;a))&amp;nbsp;m-zero)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;把&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;和&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的对应实现替换进来&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(apply&amp;nbsp;concat&amp;nbsp;(map&amp;nbsp;(fn&amp;nbsp;[a]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(odd?&amp;nbsp;a)&amp;nbsp;(list&amp;nbsp;(*&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;a))&amp;nbsp;(list)))&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;map&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;的结果是包含&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;1&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;个或&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;0&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;个元素的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;list&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;组成的序列：对于奇数的值，返回的是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;()&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，即&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的值，对于偶数，返回&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;(&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;结果&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;)&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，即&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的值。&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;concat&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;函数把这些&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;list&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;连接起来成为最后的结果。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;对于&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，一般跟&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;和&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;一起使用。一个典型的应用是查找（比如一个语法解释器，一个正则搜索，一个数据库查询），可能成功（有返回结果）或失败（无返回结果）。&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;用于把查找的结果组合返回（&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;sequence monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;），或者一直查找，直到找到一个符合条件的值（&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;）。原则上来说，使用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;比使用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;更合适，任何使用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-plus&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的地方，都可以用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-zero&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;实现。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;讲完理论，让我们熟悉几个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family: Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;。在本节的开头，我提到&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;使用的数据结构并不总是表示运算步骤的结果，有时表示的是运算步骤本身。比如，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，它的数据结构是一个函数。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;的作用是把状态算法，用纯函数式的方式来实现。状态算法需要更新一些变量的值，在命令式语言中，这很普遍，但是却不符合纯函数式编程的基本原则，因为纯函数式语言是不允许可变数据结构的。一个解决方法是在纯函数语言中使用特殊的数据项（典型的就是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;map&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;）来存储算法所需的可变数据的当前值。在命令式编程中，一个函数可以通过传参，修改变量的当前值，并返回更新后的值。对状态的修改变成显式的数据项，在函数中传递。&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;可以隐藏状态传递的过程，并且写出的算法使用命令式风格来查询和修改状态。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;和我们之前看到的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;不同，他的数据结构是一个函数，即运算本身。&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;的值是一个接受一个参数的函数，这个函数就是当前状态的运算。并且返回一个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;vector&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;vector&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;长度为&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;2&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，包括计算结果和更新后的状态。实际上，这些函数都是典型的闭包，并且你在程序中使用的代码和函数，都产生这样的闭包。就像你看到的，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;允许你组合这些函数，使你的程序看起来跟命令式的一样，尽管他们是纯函数式的。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;让我们从一个简单的常见场景开始：你要处理的&lt;/span&gt;&lt;span style="font-size:8.0pt; font-family:Verdana;color:#333333;"&gt;state&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;以&lt;/span&gt;&lt;span style="font-size:8.0pt; font-family:Verdana;color:#333333;"&gt;map&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;形式存储。你可能认为&lt;/span&gt;&lt;span style="font-size:8.0pt; font-family:Verdana;color:#333333;"&gt;map&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;是一个命令式语言中的概念，每个&lt;/span&gt;&lt;span style="font-size: 8.0pt;font-family:Verdana;color:#333333;"&gt;key&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;定义一个变量，两个基本的操作来读取和修改值。在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family: 宋体;color:#333333;"&gt;的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family: 宋体;color:#333333;"&gt;库中已经提供了这个功能，但不论如何，我这里还是要展示一下&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Comic Sans MS'; color: #0000ff; background-color: #ffff99; "&gt;（巫云&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Comic Sans MS'; color: #0000ff; background-color: #ffff99; "&gt;@&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Comic Sans MS'; color: #0000ff; background-color: #ffff99; "&gt;：如果已经引入了&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Comic Sans MS'; color: #0000ff; background-color: #ffff99; "&gt;clojure.algo.monads&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Comic Sans MS'; color: #0000ff; background-color: #ffff99; "&gt;，会发生函数名冲突，可以改名后测试）&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;首先，我们看&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: #800000; "&gt;fetch-val&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;函数，用于读取一个变量的值：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;fetch-val&amp;nbsp;[key]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[s]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[(key&amp;nbsp;s)&amp;nbsp;s]))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;这里我们定义一个生成&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;值的函数&lt;/span&gt;&lt;span style="font-size: 8pt; color: #0000ff; font-family: 'Comic Sans MS'; background-color: #ffff99; "&gt;（巫云&lt;/span&gt;&lt;span style="font-size: 8pt; color: #0000ff; font-family: 'Comic Sans MS'; background-color: #ffff99; "&gt;@&lt;/span&gt;&lt;span style="font-size: 8pt; color: #0000ff; font-family: 'Comic Sans MS'; background-color: #ffff99; "&gt;：原文为&lt;/span&gt;&lt;span style="font-size: 8pt; color: #0000ff; font-family: 'Comic Sans MS'; background-color: #ffff99; "&gt;state-monad-value-generating function&lt;/span&gt;&lt;span style="font-size: 8pt; color: #0000ff; font-family: 'Comic Sans MS'; background-color: #ffff99; "&gt;）&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;。它返回一个状态变量&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;s&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，当执行时，返回一个返回值和新状态组成的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;vector&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;。返回值是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;map&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;对应的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;key&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;值。这个函数不改变状态，只是查找。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;下面我们来看&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;set-val&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，返回前一状态的值和包含新状态的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;map&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;组成的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;vector&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-val&amp;nbsp;[key&amp;nbsp;val]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[s]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let&amp;nbsp;[old-val&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&amp;nbsp;s&amp;nbsp;key)&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;-s&amp;nbsp;&amp;nbsp;&amp;nbsp;(assoc&amp;nbsp;s&amp;nbsp;key&amp;nbsp;val)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[old-val&amp;nbsp;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;-s])))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;使用这两个元素，我们开始进行组合。我们来定义一个声明，把一个变量的值复制到另一个变量，并返回被修改变量的原值：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;copy-val&amp;nbsp;[&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;&amp;nbsp;to]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(domonad&amp;nbsp;state-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;-val&amp;nbsp;&amp;nbsp;&amp;nbsp;(fetch-val&amp;nbsp;&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old-to-val&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-val&amp;nbsp;to&amp;nbsp;&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;-val)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old-to-val))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;那么&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;copy-val&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;函数返回什么呢？一个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state-monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;值，即一个函数，接受一个参数，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;变量&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;s&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;。执行时，返回变量的旧值，和拥有有新值的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;的拷贝。让我们试一下：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(let&amp;nbsp;[initial-state&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{:a&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;:b&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;computation&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(copy-val&amp;nbsp;:b&amp;nbsp;:a)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[result&amp;nbsp;final-state]&amp;nbsp;(computation&amp;nbsp;initial-state)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;final-state)&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;结果为&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;{:a 2, :b 2}&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，正如我们期望的。但是这是如何发生的呢？为了理解&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，我们需要看一看&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;和&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的定义。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;m-result&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;没有什么特别，它返回一个函数，根据&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;s&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;，返回&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;s&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;在&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;map&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;中的值&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;v&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;，以及未更新过的状态&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: Verdana; color: #333333; "&gt;s&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 8pt; font-family: 宋体; color: #333333; "&gt;：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;m-result&amp;nbsp;[v]&amp;nbsp;(fn&amp;nbsp;[s]&amp;nbsp;[v&amp;nbsp;s]))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的实现比较有趣：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;m-bind&amp;nbsp;[mv&amp;nbsp;f]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[s]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let&amp;nbsp;[[v&amp;nbsp;ss]&amp;nbsp;(mv&amp;nbsp;s)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((f&amp;nbsp;v)&amp;nbsp;ss))))&lt;/div&gt;&lt;/div&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;显然，他返回一个以状态变量&lt;/span&gt;&lt;span style="font-size: 8.0pt;font-family:Verdana;color:#333333;"&gt;s&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;为参数的函数，执行这个函数时，首先对&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;s&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;运行&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;mv&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;（&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family: 宋体;color:#333333;"&gt;操作链中绑定的第一个声明）。返回值解析到结果&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;v&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;和新的状态&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;ss&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;。第一步的结果&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;v&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，被后面的操作&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;f&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;使用（跟我们看过的其他&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;一样）。调用的结果返回另一个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state-monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;值，它也是一个接受状态变量参数的函数。当我们进入&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;(fn [s] &amp;#8230;)&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;时，我们已经处于执行阶段，于是我们必须对状态&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;ss&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;调用这个函数。&lt;/span&gt;&lt;/p&gt;&lt;div style="font-family: 'Comic Sans MS'; font-size: 10pt; color: #0000ff; background-color: #ffff99; "&gt;（巫云：可以把(domonad state-m&lt;br /&gt;[from-val (fetch-val from)&lt;br /&gt;old-to-val (set-val to from-val)]&amp;nbsp;&lt;br /&gt;old-to-val) 展开来理解一下运行步骤。）&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;是一个非常基础的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;之一，许多&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;都是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;的变形。通常一个这样的变形在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;中增加一下东西，来说明状态已经被处理。一个例子就是&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; color: #993366; "&gt;clojure.contrib.stream-utils&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;里的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;stream monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;。它的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;描述了数据组成的流，&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;函数除了&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;基本的工作外，还检测非法值以及&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;end-of-stream&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;的条件。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;中的一个变形由于使用非常频繁，以至于成为了一个标准&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，这就是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;writer monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;。它的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;state&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;是一个累加器（在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;clojure.contrib.accumulators&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;中定义），运算可以通过&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;write&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;函数进行累加。这个名字来自一个特殊的应用程序：&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;loggin&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;，它在&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;identiy monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;（&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;let&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;就是一个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;identiy monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;）中进行了运算。假设你想增加一个运算协议，使用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;list&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;或&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;string&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;来累加计算过程中的信息，只需要修改&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;write monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;对应的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;identity monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;，然后在需要的地方调用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;write&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;这里有一个抽象的例子：著名的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family: Verdana;color:#333333;"&gt;Fibonacci&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;函数的最直接（同时也是效率最低的）实现：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;fib&amp;nbsp;[n]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(&amp;lt;&amp;nbsp;n&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let&amp;nbsp;[n1&amp;nbsp;(dec&amp;nbsp;n)&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n2&amp;nbsp;(dec&amp;nbsp;n1)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(+&amp;nbsp;(fib&amp;nbsp;n1)&amp;nbsp;(fib&amp;nbsp;n2)))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;我们来增加一个运算协议，以便看看，在整个计算过程中，发生了哪些调用。首先，我们重写这个例子，定义每一个计算步骤&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;fib&amp;nbsp;[n]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(&amp;lt;&amp;nbsp;n&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let&amp;nbsp;[n1&amp;nbsp;(dec&amp;nbsp;n)&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n2&amp;nbsp;(dec&amp;nbsp;n1)&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f1&amp;nbsp;(fib&amp;nbsp;n1)&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f2&amp;nbsp;(fib&amp;nbsp;n2)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(+&amp;nbsp;f1&amp;nbsp;f2))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;接着，我们用&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;domonad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;代替&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;let&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;，并使用带有一个&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;vetor&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;累加器的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;writer monad&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;(require&amp;nbsp;[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;clojure.contrib.accumulators&amp;nbsp;:as&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;accu])&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;(with-monad&amp;nbsp;(writer-m&amp;nbsp;accu/empty-vector)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(defn&amp;nbsp;fib-trace&amp;nbsp;[n]&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&amp;nbsp;(&amp;lt;&amp;nbsp;n&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-result&amp;nbsp;n)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(domonad&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[n1&amp;nbsp;(m-result&amp;nbsp;(dec&amp;nbsp;n))&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n2&amp;nbsp;(m-result&amp;nbsp;(dec&amp;nbsp;n1))&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f1&amp;nbsp;(fib-trace&amp;nbsp;n1)&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_&amp;nbsp;&amp;nbsp;(write&amp;nbsp;[n1&amp;nbsp;f1])&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f2&amp;nbsp;(fib-trace&amp;nbsp;n2)&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_&amp;nbsp;&amp;nbsp;(write&amp;nbsp;[n2&amp;nbsp;f2])]&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(+&amp;nbsp;f1&amp;nbsp;f2)))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;最后，我们运行&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; "&gt;fib-trace&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 宋体; "&gt;查看结果：&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;span style="font-family: 宋体; color: #ff0000; font-size: 10pt; "&gt;(fib-trace 3)&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left; background:white"&gt;&lt;span style="font-family: 宋体; color: #ff0000; font-size: 10pt; "&gt;=&amp;gt; [2 [[1 1] [0 0] [2 1] [1 1]]]&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;第一个元素，是&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;fib&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;运算执行的返回值&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;2&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;；第二个元素，是一个协议&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;vector&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;，包含每步递归调用的参数和结果。&lt;/span&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;font color="#333333" face="Verdana"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p align="left" style="text-align:left;line-height:15.6pt;background: white"&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;如果当我们把&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;write&lt;/span&gt;&lt;span style="font-size:8.0pt;color:#333333;"&gt;调用注释掉，并且把&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;类型换成&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;identity-m&lt;/span&gt;&lt;span style="font-size: 8.0pt;color:#333333;"&gt;时，就会变成一个标准的，无协议的&lt;/span&gt;&lt;span style="font-size:8.0pt;font-family:Verdana;color:#333333;"&gt;fib&lt;/span&gt;&lt;span style="font-size:8.0pt; color:#333333;"&gt;函数。请自己尝试。&lt;/span&gt;&lt;/p&gt;&lt;div style="font-family: comic sans ms; font-size:10pt;color: #0000ff; background-color: #ffff99;"&gt;巫云@：测试代码为&lt;br /&gt;(with-monad identity-m&lt;br /&gt;&amp;nbsp; (defn fib-trace [n]&lt;br /&gt;&amp;nbsp; &amp;nbsp; (if (&amp;lt; n 2)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; (m-result n)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; (domonad&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [n1 (m-result (dec n))&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;n2 (m-result (dec n1))&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;f1 (fib-trace n1)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;f2 (fib-trace n2)]&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (+ f1 f2)))))&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/20/2407456.html" title="Part 4"&gt;&lt;span style="font-size: 10pt; "&gt;Part 4&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;span style="font-family: 宋体; font-size: 10pt; "&gt;将会展示：如何通过组合名为&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;monad transformers&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;的&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;monad&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;构建组件来定义我们自己的&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;monad&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;。在演示段落，我将解释&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;probability monad&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;，以及如何通过跟&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;maybe-transformer&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;的组合把它应用到贝叶斯（&lt;/span&gt;&lt;span style="font-family: Verdana; color: #333333; font-size: 10pt; "&gt;Bayesian&lt;/span&gt;&lt;span style="font-size: 10pt; "&gt;）估算。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/darkluck99/aggbug/2404934.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/18/2404934.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/darkluck99/archive/2012/03/17/2403082.html</id><title type="text">Clojure程序员的Monad之旅（Part 2）</title><summary type="text">Clojure程序员的Monad之旅（Part 2）Monad在函数式编程中常常跟Haskell联系在一起。在Haskell中，他们在I/O等很多应用中扮演了核心角色。目前多数对monad的介绍都是为Haskell程序员编写的，尽管如此，monad可以在任何一种函数语言中使用，甚至某些语言跟Haskell想去甚远。这里，我要使用Clojure来解释monad的概念，Clojure是一种拥有强大函数编程支持的，时髦的lisp方言。</summary><published>2012-03-17T05:19:00Z</published><updated>2012-03-17T05:19:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2012/03/17/2403082.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2012/03/17/2403082.html"/><content type="html">&lt;div style="border: none; border-bottom: solid #6699CC 1.0pt; padding: 0in 0in 0in 0in; background: white;"&gt;&lt;p align="left"&gt;&lt;span&gt;翻译自&lt;/span&gt;&amp;nbsp;&lt;a href="http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-2/" title="A Monad Tutorial For Clojure Programmers (Part 2)"&gt;A Monad Tutorial For Clojure Programmers (Part 2)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p align="left"&gt;在&lt;a title="Part1" href="http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html"&gt;Part1&lt;/a&gt;中，我们已经学习了最基础的2个monad：identity monad和maybe monad。在本节中，我们继续介绍sequence monad，并联系m-result函数进行讲解。最后，我会演示示2个有用的monad泛操作符。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;sequence monad（Haskell中与之对应的是list monad）是使用频率最高的monad之一。Clojure中也内建了这个monad，比如for。让我们看下面的例子：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;for&lt;/span&gt;&amp;nbsp;[a&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b&amp;nbsp;(range&amp;nbsp;a)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(*&amp;nbsp;a&amp;nbsp;b))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;for和let在语法上很像，它们有相同的结构：一个由绑定表达式组成的list，每个绑定表达式可以使用前面表达式的符号；一个结果表达式，此表达式通常需使用前面的绑定。不同的是：let给每个符号绑定一个单值，for绑定的是一个序列。for必须绑定序列，返回结果也是序列。for可以配合条件表达式:when和:while使用。从monad的复合运算的观点来看，sequence的运算结果可以看作非单一性的，比如，运算结果不只一个的情况。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;使用monad库，上面的循环可以写成：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(domonad&amp;nbsp;sequence-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[a&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b&amp;nbsp;(range&amp;nbsp;a)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(*&amp;nbsp;a&amp;nbsp;b))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;我们已经知道，domonad宏展开为一个m-bind的操作链，并结尾调用m-result函数。下面我们要讲解如何定义m-bind和m-result，来获得循环效果。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;前面我们看到，m-bind调用一个代表剩余计算步骤的函数，参数是绑定值。为了的到循环效果，我们要重复调用这个函数。第一步我们构造一个这样的函数：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;m-bind-first-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;[sequence&amp;nbsp;function]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(map&amp;nbsp;function&amp;nbsp;sequence))&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;(m-bind-first-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[a]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-bind-first-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;(range&amp;nbsp;a)&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[b]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(*&amp;nbsp;a&amp;nbsp;b)))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;结果为：&lt;span style="color: red; "&gt;(() (0) (0 2) (0 3 6) (0 4 8 12))&lt;/span&gt;， 而for表达式的到的结果是&amp;nbsp;&lt;span style="color: red; "&gt;(0 0 2 0 3 6 0 4 8 12)&lt;/span&gt;。我们想要一个无嵌套的sequence，因为嵌套的层数跟调用m-bind的次数是相同的。既然m-bind引入一次嵌套，我们就要想办法去掉这次嵌套。这似乎可以用concat解决，那么我们再来试一下：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;m-bind-second-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;[sequence&amp;nbsp;function]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(apply&amp;nbsp;concat&amp;nbsp;(map&amp;nbsp;function&amp;nbsp;sequence)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;(m-bind-second-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[a]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-bind-second-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;(range&amp;nbsp;a)&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[b]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(*&amp;nbsp;a&amp;nbsp;b)))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;这次更糟，我们得到了一个异常。&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: red; "&gt;java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;我们来思考一下! 每次m-bind引入一层嵌套，同时消除一次嵌套。调用函数的嵌套层数决定了结果的嵌套层数。我们最终结果的嵌套层数跟（* a b）相同，即没有嵌套。那么如果我们想在结果中实现1层嵌套，跟调用多少次m-bind无关，正确的办法是在最后一次计算引入嵌套：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(m-bind-second-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;(range&amp;nbsp;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;)&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[a]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-bind-second-&lt;span style="color: #0000FF;"&gt;try&lt;/span&gt;&amp;nbsp;(range&amp;nbsp;a)&amp;nbsp;&amp;nbsp;(fn&amp;nbsp;[b]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(list&amp;nbsp;(*&amp;nbsp;a&amp;nbsp;b))))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;一切正常。我们的(fn [b] ...)始终返回一个单元素的list。内层的m-bind创建一个单元素的sequence，每个元素是b的一个值，由这些值组成一个无嵌套的list。外层的m-bind，创建的是a的值组成的list。每个m-bind的结果同样是一个无嵌套的list。这很好的表现了m-result在monad中的作用。Sequence monad的最终定义如下：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;m-bind&amp;nbsp;[sequence&amp;nbsp;function]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(apply&amp;nbsp;concat&amp;nbsp;(map&amp;nbsp;function&amp;nbsp;sequence)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;m-result&amp;nbsp;[value]&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(list&amp;nbsp;value))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;m-result的作用是，当出现在monad绑定的右侧时返回一个值，把符号绑定到这个值。在定义monad时，m-bind和m-result必须满足这个条件。在Clojure代码中表现为：&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;(= (m-bind (m-result value) function)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp; (function value))&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;还有其它两个monad规则，其中一个是：&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;(= (m-bind monadic-expression m-result)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp; monadic-expression)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;monadic-expression代表任何有效的monad表达式，例如一个sequence monad表达式。使用domonad宏可以更清楚的理解这个规则&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;(= (domonad&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [x monadic-expression]&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp; monadic-expression)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;最后一个规则是&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;(= (m-bind (m-bind monadic-expression&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function1)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function2)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp; (m-bind monadic-expression&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (fn [x] (m-bind (function1 x)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function2))))&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;使用domonad表示&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;(= (domonad&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [y (domonad&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [x monadic-expression]&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (function1 x))]&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (function2 y))&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp; (domonad&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [x monadic-expression&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; y (m-result (function1 x))]&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #008000; "&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (function2 y)))&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;使用monad时不需要记住这些法则，除非你要创建自己的monad。你需要记住的是(m-result x)代表值为x的monad运算。我们前面讲过的identity monad和maybe monad，没有特别的monad表达式，此时m-result只是identity函数&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;现在放松一下&lt;img src="http://www.cnblogs.com/Emoticons/QQ/laf.gif" alt="" /&gt;。关于monad的理论我们下一节再讨论，那时我还会告诉你一些关于for中使用:when的事情。本节剩余部分主要是编程实践。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;我们也许要问，既然Clojure已经有个let和for，为什么还要制造identity monad和sequence monad呢？答案就是在各种monad中有可共用的泛操作。使用monad库，你可以写一个函数，把monad作为参数，并在给定的monad中组合多个运算。我待会用一个抽象示例来演示。Monad库还包括许多可在任何monad中使用的操作，它们的名字都以&amp;#8220;m-&amp;#8221;开头。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;使用最频繁的monad泛函数是m-lift，它把一个参数为n个值参数的函数，转换成一个参数为n个monad表达式，并且返回值也是monad表达式的函数。这个新函数隐式调用了m-bind和m-result。举个简单的例子：&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(def&amp;nbsp;nil-respecting-addition&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(with-monad&amp;nbsp;maybe-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-lift&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;+)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;这个函数返回两个参数的和，类似+，区别是它在任何参数为nil的情况下都返回nil。记住，m-lift必须指定函数需要的参数个数，这个信息是无法从函数中获得的。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;我们用domonad写出等效的表达式，以便看清m-lift的工作原理&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defn&amp;nbsp;nil-respecting-addition&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[x&amp;nbsp;y]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(domonad&amp;nbsp;maybe-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[a&amp;nbsp;x&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b&amp;nbsp;y]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(+&amp;nbsp;a&amp;nbsp;b)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;看得出，m-lift对每个参数调用了一次m-result和m-bind。同样的定义，如果使用sequence monad，将会返回一个函数，这个函数返回一个求和的sequence，它的值是从两个输入的sequence中计算得来。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="color: #ff0000; "&gt;练习：下面的函数跟Clojure的哪个著名的内建函数等效呢？&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(with-monad&amp;nbsp;sequence-m&lt;br /&gt;&amp;nbsp;&amp;nbsp;(defn&amp;nbsp;mystery&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[f&amp;nbsp;xs]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((m-lift&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;f)&amp;nbsp;xs&amp;nbsp;)))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left" style="background-color: #ffff99; "&gt;&lt;span style="font-family: 'Comic Sans MS'; font-size: 10pt; color: #0000ff; "&gt;巫云@：从函数结构巫云认为这个好像是map嘛，我们来试一下&lt;/span&gt;&lt;font color="#0000ff" face="'Comic Sans MS'" size="2"&gt;&lt;span style="line-height: 19px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="font-family: 'Comic Sans MS'; font-size: 10pt; color: #0000ff; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;/span&gt;&lt;span style="color: #0000ff; font-family: 'Comic Sans MS'; font-size: 10pt; "&gt;mystery&lt;/span&gt;&amp;nbsp;&lt;span style="font-family: 'Comic Sans MS'; font-size: 10pt; color: #0000ff; "&gt;#(* 2 %) [1 2 3 4 5])&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Comic Sans MS'; font-size: 10pt; color: #0000ff; "&gt;返回结果：(2 4 6 8 10)，果然跟map一样哦。&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;另一个常用的monad泛函数是m-seq，他接受一个monad 表达式组成的sequence，返回一个结果值的sequence。根据domonad的规则，（m-seq [a b c]）相当于&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;(domonad&lt;br /&gt;&amp;nbsp;&amp;nbsp;[x&amp;nbsp;a&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;b&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;z&amp;nbsp;c]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;(x&amp;nbsp;y&amp;nbsp;z))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;使用m-seq的例子，请自己来试一下&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(with-monad&amp;nbsp;sequence-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(defn&amp;nbsp;ntuples&amp;nbsp;[n&amp;nbsp;xs]&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(m-seq&amp;nbsp;(replicate&amp;nbsp;n&amp;nbsp;xs))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;巫云@：我们来测试一下 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;(ntuples 1 [1 2 3]) =&amp;gt; ((1) (2) (3))&lt;br /&gt;&amp;nbsp;(ntuples 2 [1 2 3]) =&amp;gt; ((1 1) (1 2) (1 3) (2 1) (2 2) (2 3) (3 1) (3 2) (3 3))&lt;br /&gt;&lt;br /&gt;&amp;nbsp;因为使用了sequence-m，我们可以想象成这是n层的循环。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;最后介绍m-chain，它接受一个单参数操作组成的list。然后把这些操作组成一个链，并使每个参数从操作链上流过。比如：（m-chain [a b c]）等价于&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(fn&amp;nbsp;[arg]&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(domonad&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[x&amp;nbsp;(a&amp;nbsp;arg)&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;(b&amp;nbsp;x)&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z&amp;nbsp;(c&amp;nbsp;y)]&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;一个常用的例子是层级结构的遍历。Clojure的parents函数通过使用multimethod，返回一个类的的所有基类和接口。下面的函数以parents为基础，寻找一个类的第n代祖先。&lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(with-monad&amp;nbsp;sequence-m&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(defn&amp;nbsp;n-th-generation&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[n&amp;nbsp;cls]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((m-chain&amp;nbsp;(replicate&amp;nbsp;n&amp;nbsp;parents))&amp;nbsp;cls&amp;nbsp;)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;&amp;nbsp;(n-th-generation&amp;nbsp;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&amp;nbsp;[]))&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt;&amp;nbsp;(n-th-generation&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&amp;nbsp;[]))&lt;br /&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt;&amp;nbsp;(n-th-generation&amp;nbsp;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&amp;nbsp;[]))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="background-color: #ffff99; font-family: 'Comic Sans MS'; font-size: 10pt; color: #0000ff; "&gt;巫云@：这个例子相当于把n次parents操作组成了一个操作链&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;你可能发现了，有些类在结果中出现了不只一次，因为他们是很多类的基类。事实上，我们应该使用sets代替sequence来表现结果，这并不难，把sequence-m，替换成set-m即可。&lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;在Part3，我会讲:when条件表达式在循环中的使用，并且看看他们在monad中是如何实现的，并且还会介绍其它几个monad。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/darkluck99/aggbug/2403082.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/17/2403082.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html</id><title type="text">Clojure程序员的Monad之旅（Part 1）</title><summary type="text">Monad在函数式编程中常常跟Haskell联系在一起。在Haskell中，他们在I/O等很多应用中扮演了核心角色。目前多数对monad的介绍都是为Haskell程序员编写的，尽管如此，monad可以在任何一种函数语言中使用，甚至某些语言跟Haskell想去甚远。这里，我要使用Clojure来解释monad的概念，Clojure是一种拥有强大函数编程支持的，时髦的lisp方言。</summary><published>2012-03-16T09:57:00Z</published><updated>2012-03-16T09:57:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html"/><content type="html">&lt;div style="border: none; border-bottom: solid #6699CC 1.0pt; padding: 0in 0in 0in 0in; background: white;"&gt;&lt;p&gt;&lt;span style="font-family: Tahoma, sans-serif; background-color: white;"&gt;翻译自&amp;nbsp;&lt;/span&gt;&lt;a style="font-family: Tahoma, sans-serif; background-color: white;" title="A Monad Tutorial For Clojure Programmers (Part 1)" href="http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/"&gt;A Monad Tutorial For Clojure Programmers (Part 1)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;span style="color: #cccccc; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Comic Sans MS'; background-color: #ffff99; font-size: 10pt; color: #0000ff;"&gt;译者注，在一些Clojure同学的要求下，翻译了这个系列，虽然是09年的老文章了，但是讲解了FP的一些重要概念，不妨一读。&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;M&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;4times new roman&amp;quot;;color: #333333;"&gt;ona&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;d&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;在函数式编程中常常跟&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Haskell&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;联系在一起。在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Haskell&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;中，他们在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;I/O&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;等很多应用中扮演了核心角色。目前多数对&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的介绍都是为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Haskell&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;程序员编写的，尽管如此，&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;可以在任何一种函数语言中使用，甚至某些语言跟&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Haskell&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;想去甚远。这里，我要使用&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;来解释&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的概念，&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;是一种拥有强大函数编程支持的，时髦的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;lisp&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;方言。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的库：&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;4times new roman&amp;quot;;color: #333333;"&gt;&lt;a href="http://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/monads.clj"&gt;&lt;span style="color: #6699cc; text-decoration: none; text-underline: none;"&gt;clojure.contrib.monads&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;实现了&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;首先，在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;REPL&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;中引入这个库&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (use &lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;clojure.contrib.monads) &lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;巫云@：clojure升级到1.3以后，monads的库被移出contrib，目前在clojure.algo.monads中，可从maven下载，用leiningen的同学参考我前面的文章&lt;a title="《64位window7下配置Clojure+Emacs开发环境》" href="http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html"&gt;《64位window7下配置Clojure+Emacs开发环境》&lt;/a&gt;：在project1.clj的:dependencies节，增加[org.clojure/algo.monads "0.1.0"]，重新运行lein deps，下载需要的库。引入库的代码也相应改成(use 'clojure.algo.monads)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Monad &lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;用来把多个运算步骤组合成一个更大的多步运算。让我们来创建一个最简单的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;，这个&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Haskell&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;中被称为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;identiy monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。实际上&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;语言已经内建了这个机制，而且你一定使用过，它就是&lt;/span&gt;&lt;a href="http://clojure.org/special_forms#let"&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F; text-decoration: none; text-underline: none;"&gt;let&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;看下面的代码：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;(let [a &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;br/&gt;b (inc a)]&lt;br /&gt;&lt;br/&gt;(* a b))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;它可以被理解为一个&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;3&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;步运算：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; color: #333333;"&gt;1.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; "&gt;计算&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 10pt; font-family: 'Courier New';"&gt;1&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; "&gt;（常量），结果叫做&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 10pt; font-family: 'Courier New';"&gt;a&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; color: #333333;"&gt;2.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; "&gt;计算&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 10pt; font-family: 'Courier New';"&gt;(inc a)&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; font-family: Verdana, sans-serif; color: #333333;"&gt;,&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; "&gt;结果叫做&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 10pt; font-family: 'Courier New';"&gt;b&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; font-family: Verdana, sans-serif; color: #333333;"&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; color: #333333;"&gt;3.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; "&gt;计算&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 10pt; font-family: 'Courier New';"&gt;(* a b)&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; font-family: Verdana, sans-serif; color: #333333;"&gt;,&lt;/span&gt;&lt;span style="background-color: white; line-height: 15.6pt; font-size: 9pt; "&gt;结果作为整个多步运算的结果&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;每一步都访问了前一个步骤运算结果绑定到的符号&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;现在假设&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt; Clojure&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;没有&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;表达式，我们可以使用什么办法来达到同样的效果呢？对，我们可以使用函数，下面的表达式实现了这个效果：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; ( (fn [a] ( (fn [b] (* a b)) (inc a) ) ) &lt;span style="color: #800080;"&gt;1&lt;/span&gt; )&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;最外层参数为&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F;"&gt;a&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的匿名函数，接受的参数是&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F;"&gt;1&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，通过这种方式，我们把&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;绑定到&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;a&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。在这个函数内部，使用同样的结构，使参数为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;b&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的函数，调用&lt;/span&gt; &lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;（&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;inc a&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;）作为他的传入参数。可以在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;REPL&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;中验证，结果与&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;形式的一致。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;当然，我们不仅仅为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;重新造个轮子。这个计算步骤看起来与表达的相反，而且整个结构难于理解。但是我们可以通过一个小的辅助函数&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，使运算顺序变成从右向左的。这里我们把他成为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;（&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;），这也是他在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;Clojure&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;库中的名字。首先，我们定义函数：&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;（注，如果已经引入了&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #0000ff;"&gt;monads&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;库，会提示名称冲突，可以换个名字）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (defn m-bind [value function]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; (function value))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;正如你看到的，他的工作很简单，但是却令参数值在函数左边传入成为可能。使用&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，我们可以这样写：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (m-bind &lt;span style="color: #800080;"&gt;1&lt;/span&gt; (fn [a]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; (m-bind (inc a) (fn [b]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; (* a b)))))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;现在，这个方式，还是不如&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;做的漂亮，但是我们已经离目标更近了。有一个宏可以把&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;转换成由&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;组合成的一个操作链，这个宏就是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;domonad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。现在我们可以这样写我们的例子：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (domonad identity-m&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; [a &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; b (inc a)]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; (* a b))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;现在这已经看起来跟&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;方式几乎没什么差异了，&lt;/span&gt;&amp;nbsp;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;运行&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F;"&gt;macroexpand-1&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;把宏展开&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (clojure.contrib.monads/with-monad identity-m&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; (m-bind &lt;span style="color: #800080;"&gt;1&lt;/span&gt; (fn [a] (m-bind (inc a) (fn [b] (m-result (* a b)))))))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;通过结果我们看到，在一个&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F;"&gt;(with-monad identity-m ...)&lt;/span&gt;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;; color: #84939F;"&gt;定义&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;的块中，通过&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;;color: #333333;"&gt;组成了一个操作链，并调用&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; times new roman&amp;quot;;color: #84939F;"&gt;m-result&lt;/span&gt;&amp;nbsp;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;;color: #333333;"&gt;（后面解释）。对于&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; color: #333333;"&gt;identiy monad&lt;/span&gt;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;;color: #333333;"&gt;（&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; color: #333333;"&gt;indentiy-m&lt;/span&gt;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;;color: #333333;"&gt;）来说，&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; color: #333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;;color: #333333;"&gt;就是&lt;/span&gt;&lt;span style="font-size: 10.0pt; font-family: 'Courier New'; color: #333333;"&gt;identiy-&lt;/span&gt;&lt;span style="font-size: 10.0pt; courier new&amp;quot;4courier new&amp;quot;;courier new&amp;quot;;color: #333333;"&gt;它的名字。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;你可能已经猜到，&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的泛型化，通过把&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;替换为其他函数，可以创造更多的功能。每个&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;定义了对&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的实现，并实现对应的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。通过一个&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;with-monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;块，把这些实现绑定起来。这样，你就可以用一单个表达式来组合多个步骤。通常情况下，我们是用&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;domonad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;宏，它可以帮助我们做这些事情&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;在第二个例子中，我们将看到另一个简单的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，但是它能带给你在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;let&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;中你没有发现的知识。假设，你的运算有时可能失败，这时要返回&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。我们来写这样一个函数：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (defn f [x]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; (let [a x&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; b (inc a)]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; (* a b)))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;在一个可能失败的运算中，我们想在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;x&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;或者（&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;inc a&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;）产生&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的时候返回&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。当然了，（&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;inc a&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;）永远多不会返回&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，这里只是做个例子。无论如何，这个思想的中心就是当任何运算步骤产生的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，最终结果就是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，剩下的步骤将被取消。我们需要做出一些改动：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (defn f [x]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; (domonad maybe-m&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; [a x&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; b (inc a)]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; (* a b)))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;这个&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;maybe monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，代表着运算的结果可能是有效值，也可能是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;。他的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;函数仍然是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;identiy&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，这里我们就略过对&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的讨论（在第二部分中将详细介绍）。所有的神奇都在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;函数中：&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;（注：每个不同的&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #0000ff;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;，差别就在于对&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #0000ff;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;和&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #0000ff;"&gt;m-result&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;的不同实现，这里可以看到&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #0000ff;"&gt;identity-m&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;和&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: Verdana, sans-serif; color: #0000ff;"&gt;maybe-m&lt;/span&gt;&lt;span style="font-size: 9pt; color: #0000ff;"&gt;的区别）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; (defn m-bind [value function]&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (nil? value)&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; nil&lt;br /&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; (function value)))&lt;/div&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;当&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;value&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;参数的值不是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;时，调用&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;function&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;函数，与&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;indentiy monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;做的工作一样。记住，这个函数的效果影响了所以的计算步骤。如果&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;value&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;为&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，那么&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;返回&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，剩余的计算都不会被执行。当调用（&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;f 1&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;）返回的是&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;2&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;；当调用（&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;f nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;），返回&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，无需在每一步的计算中添加检测&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;nil&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;的代码，&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;m-bind&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;悄悄的为你做了这些事。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;在&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;; color: #333333;"&gt;part2&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;; color: #333333;"&gt;中，我将介绍更多的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;，并且讨论一些在任何用于辅助组合运算的&lt;/span&gt;&lt;span style="font-size: 9.0pt; font-family: 'Verdana','sans-serif'; times new roman&amp;quot;;color: #333333;"&gt;monad&lt;/span&gt;&lt;span style="font-size: 9.0pt; times new roman&amp;quot;;color: #333333;"&gt;中都能使用的泛型函数。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; color: #cccccc; font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #ffff99; font-family: 'Comic Sans MS'; font-size: 10pt;"&gt;&lt;p&gt;&lt;span style="color: #0000ff;"&gt;关于monad，dict.cn解释为：单位，单一体，单细胞生物，一价原子&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;我的理解，在函数式语言中，monad指通过一种形式，把多个运行步骤组合在一起的方式&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/darkluck99/aggbug/2400714.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/16/2400714.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/darkluck99/archive/2012/03/12/2392172.html</id><title type="text">关于Lisp的真相</title><summary type="text">学习 lisp 将改变你的人生。你的脑袋会变得超出你想象得大。你会把你所有的程序都用随便的几行重写。社会将抛弃你，你也将抛弃社会。你将会开始对身边的任何人和任何事不满。</summary><published>2012-03-12T09:42:00Z</published><updated>2012-03-12T09:42:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2012/03/12/2392172.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2012/03/12/2392172.html"/><content type="html">&lt;div style="text-align: left; background-color: #ffffff; font-family: 'Trebuchet Ms', verdana, arial, sans-serif; color: #000044; font-size: 12pt; line-height: 14pt; border-bottom-width: 1pt; border-bottom-style: solid; border-bottom-color: #888866; margin-top: -3pt; margin-right: -3pt; margin-left: -3pt; margin-bottom: 4pt; background-image: url('http://secretgeek.net/backteaser.png'); background-repeat: repeat no-repeat; padding: 3pt;"&gt;&lt;p&gt;&lt;br /&gt; 本文揭露 Lisp 的真相，并列出一些可选的替代品。&lt;/p&gt;&lt;/div&gt;&lt;p&gt;(转载自：&lt;a href="http://blog.sina.com.cn/s/blog_54a7c4d201013irb.html"&gt;http://blog.sina.com.cn/s/blog_54a7c4d201013irb.html&lt;/a&gt;&amp;nbsp;)&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;学习 lisp 将改变你的人生。&lt;/p&gt;&lt;p&gt;你的脑袋会变得超出你想象得大。&lt;/p&gt;&lt;p&gt;你会把你所有的程序都用随便的几行重写。&lt;/p&gt;&lt;p&gt;社会将抛弃你，你也将抛弃社会。&lt;/p&gt;&lt;p&gt;你将会开始对身边的任何人和任何事不满。&lt;/p&gt;&lt;p&gt;Lisp 是这样的简单，以至于你可以只需要用几分钟来学习它。现在我就刚学会它，就在我等公车的时候。&lt;/p&gt;&lt;p&gt;Lisp 是这样的简单，以至于&lt;a style="text-decoration: none; color: #074387;" href="http://www.faqs.org/faqs/lisp-faq/part1/section-5.html" target="_blank"&gt;你可以用任何语言实现它，只需要简单的几页代码&lt;/a&gt;。然而这事基本不会发生，因为一旦你学会了 lisp 你就不会再想要用除 lisp 之外的任何语言写任何东西。所以你也就会对用 lisp 之外的其他语言来实现 lisp 感到厌烦。&lt;/p&gt;&lt;p&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://cogsci.ucsd.edujustinking73.webhost4life.com/batali/lisp-course/lisp-in-lisp-1.html" target="_blank"&gt;Lisp 可以完全地用 lisp 来实现&lt;/a&gt;。我刚刚完整地用 lisp 实现了 lisp，就在我跳上一辆公车并买票的瞬间。&lt;/p&gt;&lt;p&gt;当你变成一个 lisper ，你会嘲笑所有的笑话，因为再没有什么人的想法会是有趣的。你会知道一些无法用普通命令式语言表达的东西。&lt;/p&gt;&lt;p&gt;当人们做些像跟你说&amp;ldquo;嗨，你好吗？&amp;rdquo;这样的事时，你会觉得他们都是白痴。因为一个 lisper 根本不需要使用这么具体的构造。 Lisp 抽象出交互当中的那些模式使它们完全不相关。跟一个 lisper 伙计打招呼的正确方式是只需要轻轻地点一下下巴，以及大约十分之一程度的眨左眼，然后指向&lt;a style="text-decoration: none; color: #074387;" href="http://www.cabochon.comjustinking73.webhost4life.com/stevey/blog-rants/tin-foil-hats.html" target="_blank"&gt;你的锡纸帽&lt;/a&gt;。他们就会明白你的意思。如果他们不明白，那么他们就不是真正的 lisp 程序员，那么也就没什么关系。&lt;/p&gt;&lt;p&gt;Lisp&amp;nbsp;&lt;a style="text-decoration: none; color: #074387;" href="http://www-formal.stanford.edu/jmc/history/lisp/lisp.html" target="_blank"&gt;很久以前就被发明出来&lt;/a&gt;了，在 java 之前，在 C 之前，在 fortran 之前，在计算机之前，在人类之前，在地球被建立之前。宇宙本身就是一个 lisp 程序，这事一点也不重要，以至于没有一个真正的 lisper 愿意实现它。&lt;/p&gt;&lt;p&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://cs.umaine.edujustinking73.webhost4life.com/chaitin/lisp.html" target="_blank"&gt;Lisp 是如此的优雅&lt;/a&gt;以至于你只要接触它一丢丢点，就会让你好像取得了一个演出季的皇家芭蕾舞团舞者资格一样。你会穿着你的 tutu （芭蕾舞超短裙）跑出去到大庭广众面前，然后仅用你的脚尖在空气中画出一朵朵的圆括弧。&lt;/p&gt;&lt;p&gt;只有 lisper 能真正定义何为有趣。也许 ML 语言也能。今天所有的语言都&lt;a style="text-decoration: none; color: #074387;" href="http://www.technicat.com/writing/lisp.html#It's+Really+Lisp" target="_blank"&gt;基于 fortran 和 lisp&lt;/a&gt;。不好的部分来自 fortran ，好的来自 lisp。&lt;/p&gt;&lt;p&gt;如果你用 lisp 用得足够好，你会立刻对 lisp 感到失意。&amp;nbsp;&lt;a style="text-decoration: none; color: #074387;" href="http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html" target="_blank"&gt;Lisp 不是一个合格的 lisp&lt;/a&gt;&amp;nbsp;。这时我的公车开过了两个街区，我写了一些简单的 lisp 宏。它们非常强大，它们使得 lisp 完全过时了，它们作为一门新的语言替代了 lisp 。幸运的是，这门新的语言还是叫做 lisp 。而且我可以证明（从数学上证明），我刚创造的这个新的 lisp 从各种你能想到的方面都远比 lisp 好得多，而同时它又在各种你能想到的方面都等同于 lisp 。我对此很兴奋。 同时又感到很乏味。&lt;/p&gt;&lt;p&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://programming.reddit.com/" target="_blank"&gt;Reddit&lt;/a&gt;&amp;nbsp;证明了 lisp 确实很牛逼。&amp;nbsp;&lt;a style="text-decoration: none; color: #074387;" href="http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;q=reddit+site:paulgraham.com" target="_blank"&gt;Paul Graham&lt;/a&gt;&amp;nbsp;最初是用 lisp 写的 reddit ，当时他正在餐桌旁等他的咖啡。 Reddit 是如此的牛逼，以至于它&lt;a style="text-decoration: none; color: #074387;" href="http://www.aaronsw.com/weblog/rewritingreddit" target="_blank"&gt;必须被用 python 重写&lt;/a&gt;，这样他才能被普通计算机理解。因为它是用 lisp 写成的，所以重写它并没有花费什么努力，重写工作在两个处理器周期之内就完成了。&amp;nbsp;&lt;a style="text-decoration: none; color: #074387;" href="http://www.paulgraham.com/lisp.html" target="_blank"&gt;Paul Graham&lt;/a&gt;&amp;nbsp;他本人就是完全由他本人的早期版本用 lisp 写成的。这个他本人的早期版本，也是用 lisp 写的，是由更更早版本的 lisp 操刀的。这就是 lisp, paul graham, lisp, paul graham, 无穷无尽。&lt;/p&gt;&lt;p&gt;因为我们达到了&lt;a style="text-decoration: none; color: #074387;" href="http://en.wikipedia.org/wiki/Moore" target="_blank"&gt;摩耳定律的极限&lt;/a&gt;，未来的计算机具有&lt;a style="text-decoration: none; color: #074387;" href="http://www.knowing.net/PermaLink,guid,753006f4-48d0-4afe-ae1c-a96d96875cf8.aspx" target="_blank"&gt;非常多核的处理器&lt;/a&gt;并且所有的程序都必须用 haskell 和 lisp 的组合来写。这组合太过牛逼，以至于这些未来的计算机要实现我们的任何想法，都必须创建时间旅行算法来跟更遥远的未来的其他计算机借用处理能力。这听上去很难，不过在 lisp 里却没什么。在 haskell 里这是一个内建特性，对于任何一个懂得 lisp 或者 haskell 的人来说实现它都只需要用很无脑的方式。&lt;/p&gt;&lt;p&gt;在那之后，未来的计算机将被称作 Lisputer 。它的速度将使用 Lispunit 来衡量。Lispunit 表示有多少关于 lisp 不足的争论可以同时被无穷数量的 lisp 专家提出和驳回并最终毫无结论。今天的计算机的运行低于一个 lispunit 。 Lisputer 运行会达到很多 Lispunit 。Lisp 将会是使用普通数字能表示的宇宙基础最大常量。可以充满自信地说：它的结尾会是无穷数量的右括号。&lt;/p&gt;&lt;hr style="color: #323e32; font-family: simsun; text-align: left; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; border-image: initial; border-top-style: solid; border-top-color: #ddbbaa;" /&gt;&lt;p&gt;&lt;span style="word-wrap: normal; word-break: normal;"&gt;到此为止，我今天在公车上读了一篇关于 lisp 的文章。置顶文章。所有（其他）关于 lisp 的文章都真的太满了 &amp;mdash;&amp;mdash; 我的脑子开始冒出我的耳朵。这一篇：&amp;nbsp;&lt;/span&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://blogs.msdn.com/sriram/archive/2006/01/15/lisp_is_sin.aspx"&gt;lisp is sin&lt;/a&gt;&lt;span style="word-wrap: normal; word-break: normal;"&gt;&amp;nbsp;，是&amp;nbsp;&lt;/span&gt;&lt;span style="word-wrap: normal; word-break: normal;"&gt;Sriram Krishnan 写的。文中他谈到了用 C# 来工作，用 Lisp 做兴趣爱好。他还谈到了一些从 C# 转向 lisp 的方法。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;这里是一些那篇文章的评论里建议的有 lisp 瘾的人使用的替代品：&lt;/p&gt;&lt;ol style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; color: #323e32; text-align: left; font-family: Georgia, serif; line-height: 15px; border-width: 0px; padding: 0px;"&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.newlisp.org/"&gt;newLisp&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.dcs.napier.ac.uk/course-notes/sml/"&gt;ML&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://dev.perl.org/perl6/"&gt;Perl6&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.nermerle.org/"&gt;nermerle&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.smalltalk.org/"&gt;smalltalk&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.biolisp.org/"&gt;biobike&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.scheme.com/"&gt;chez scheme&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.ccs.neu.edu/home/will/Larceny/"&gt;Common Larceny&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.w3.org/TR/xslt"&gt;XSLT&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://en.wikipedia.org/wiki/OCaml"&gt;OCaml&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.lsharp.org/"&gt;LSharp&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://www.lua.org/"&gt;Lua&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://research.microsoft.com/Comega/"&gt;C Omega&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://research.microsoft.com/projects/ilx/fsharp.aspx"&gt;F#&lt;/a&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 30px; padding-top: 0px; padding-right: 0px; padding-bottom: 4pt; padding-left: 0px; border-style: initial; border-color: initial; border-image: initial; list-style-type: decimal; list-style-position: initial; list-style-image: none; font-size: small; border-width: 0px;"&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://msdn.microsoft.com/data/linq/"&gt;C# with Linq&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;还有一个人建议移植 python 的库到 lisp 。&lt;/p&gt;&lt;p&gt;奇怪为啥没提到 Ruby （参考&amp;nbsp;&lt;a style="text-decoration: none; color: #074387;" href="http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp"&gt;Why Ruby is an acceptable lisp&lt;/a&gt;&amp;nbsp;，还有&amp;nbsp;&lt;span style="word-wrap: normal; word-break: normal;"&gt;steve yegge 的回应：&lt;/span&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html"&gt;'lisp is not an acceptable lisp'&lt;/a&gt;&amp;nbsp;）&lt;/p&gt;&lt;p&gt;（后记：第一个发评论说&amp;ldquo; Paul Graham 没有写 reddit &amp;rdquo; 的人应该奖一个棒棒糖。）&lt;/p&gt;&lt;p&gt;&lt;a style="text-decoration: none; color: #074387;" href="http://secretgeek.net/lisp_truth.asp" target="_blank"&gt;原文更精彩！&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/darkluck99/aggbug/2392172.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/03/12/2392172.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html</id><title type="text">64位window7下配置Clojure+Emacs开发环境</title><summary type="text">为了学习Clojure，我最近特别在windows下配置了基于Emacs的Clojure开发环境。把过程做个记录，跟大家分享一下。过程不算太复杂，关键是要多使用Google来解决问题，有些版本问题比较难解决，耐心多尝试就能成功。很多同学都说使用linux更合适等等，我觉得确实有道理，但windows毕竟是很多程序员每天工作必用的工具，使用起来方便的多，所以还是有必要折腾一把。</summary><published>2012-02-20T09:25:00Z</published><updated>2012-02-20T09:25:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html"/><content type="html">&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;为了学习&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;Clojure&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;，我最近特别在&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;windows&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;下配置了基于&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;Emacs&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;的&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;Clojure&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;开发环境。把过程做个记录，跟大家分享一下&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;。&lt;/span&gt;&lt;span style="font-size: 12pt; font-family: Georgia; "&gt;过程不算太复杂，关键是要多使用&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;Google来解决问题，有些版本问题比较难解决，耐心多尝试就能成功。很多同学都说使用linux更合适等等，我觉得确实有道理，但windows毕竟是很多程序员每天工作必用的工具，使用起来方便的多，所以还是有必要折腾一把。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;开始了，首先我的操作系统是&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;64位的windows7，英文版。随着现在内存的价格下降，64位win7系统已经开始成为程序员的主要工作平台，所以我们配置的开发环境也要能支持64位win7才算合格。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;具体步骤：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;1.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;安装&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;jdk，因为Clojure是基于JVM的语言，所以java开发环境肯定是必装的。我们直接下载Oracle官方的64位安装包，1.7的最新版本：jdk-7u2-windows-x64.exe。下载完毕后双击安装即可。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;安装完毕，添加环境变量&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;JAVA_HOME，内容为jdk的系统路径。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;例如：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;JAVA_HOME =&amp;gt; D:\Program Files\Java\jdk1.7.0_02&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;PATH =&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 16px; line-height: 18px; "&gt;D:\Program Files\Java\jdk1.7.0_02\bin&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;打开终端，测试，输入&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;java &amp;#8211;version回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;img src="http://images.cnblogs.com/cnblogs_com/darkluck99/Untitled1.png" width="578" height="221" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;2.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;安装&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;maven2，maven是java开发常用的项目构建工具，提供jar包的管理功能，因为leiningen需要使用maven的软件仓库进行包的管理，因此，我们先要安装maven2。从官方下载压缩包，我下载的是2.2.1版&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;下载网站：&lt;/span&gt;&lt;a href="http://maven.apache.org/download.html"&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;http://maven.apache.org/download.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;下载完毕，解压到本地目录，我放置在&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;D:\new\apache-maven-2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;添加环境变量：&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;各位同学请输入自己的路径&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;M2_HOME =&amp;gt; D:\new\apache-maven-2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;M2 =&amp;gt; D:\new\apache-maven-2\bin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;MAVEN_OPTS =&amp;gt; -Xms256m -Xmx512m&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;PATH =&amp;gt; %M2%&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;打开终端，测试，输入&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;mvn --version回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="宋体"&gt;&lt;span style="font-size: 12px; line-height: 13px;"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/darkluck99/Untitled2.png" width="580" height="301" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;3.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;安装&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;leiningen，leiningen是基于Clojure的项目构建工具，可以为Clojure项目打包解决项目依赖，这也是我们这次配置中要使用的主要工具。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;下载&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;leiningen的windows压缩包和jar包（这里注意，不要用1.62的安装脚本安装，运行后面步骤时会出现错误），我下载的是：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;leiningen-1.5.2-win.zip和leiningen-1.7.0-SNAPSHOT-standalone.jar&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;下载网站：&lt;/span&gt;&lt;a href="https://github.com/technomancy/leiningen/downloads"&gt;&lt;span style="font-size: 12pt; font-family: Georgia; "&gt;https://github.com/technomancy/leiningen/downloads&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;下载完毕，&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;leiningen-1.5.2-win.zip解压缩到本地目录。我放置在D:\new\lein，同时把leiningen-1.7.0-SNAPSHOT-standalone.jar拷贝到这个文件夹下面&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;添加环境变量：各位同学请输入自己的路径&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;Path =&amp;gt; D:\new\lein &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;LEIN =&amp;gt; D:\new\lein&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;LEIN_JAR =&amp;gt; d:\new\lein\leiningen-1.7.0-SNAPSHOT-standalone.jar&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt;打开终端，测试，输入&lt;/span&gt;&lt;span style="line-height: 115%; font-size: 12pt; font-family: Georgia; "&gt; lein version回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9pt; line-height: 115%; font-family: 宋体; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/darkluck99/Untitled4.png" width="580" height="249" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;安装&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;leiningen插件：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;swank-clojure，用于Emacs的repl插件，集成了SLIME功能。使用命令&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;lein plugin install swank-clojure 1.4.0&lt;/span&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;lein&lt;/span&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;会自动下载相关依赖并安装&lt;/span&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;swank-clojure&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;至此，&lt;/span&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;lein&lt;/span&gt;&lt;span style="line-height: 115%; color: #333333; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; font-family: Georgia; font-size: 12pt; background-position: initial initial; background-repeat: initial initial; "&gt;安装完毕&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;4.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;安装&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;Emacs，Emacs是一个多功能的文本编辑工具，可谓大名顶顶，是Hacker们的最爱。我们下载最新的Emacs2.4版。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;下载地址：&lt;/span&gt;&lt;a href="https://code.google.com/p/emacs-for-windows/updates/list"&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;https://code.google.com/p/emacs-for-windows/updates/list&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;压缩包解压到本地路径。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;安装&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;Clojure&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;插件&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;clojure-mode&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;下载地址&lt;/span&gt;&lt;a href="https://github.com/jochu/clojure-mode"&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;https://github.com/jochu/clojure-mode&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;只下&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;clojure-mode.el&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;即可，下载完毕放到&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;Emacs&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;的默认插件目录下面&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;在&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;win7下，Emacs的默认插件目录是C:\Users\用户名\AppData\Roaming\.emacs.d\&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;由于&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;AppData是隐藏文件，要注意。我放置的路径是C:\Users\Adam\AppData\Roaming\.emacs.d\clojure-mode\&lt;/span&gt;&lt;span style="font-family: Georgia; font-size: 12pt; "&gt;clojure-mode.el&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;Emacs的默认配置文件夹是C:\Users\用户名\AppData\Roaming，配置文件名是.emacs。如果文件不存在，可以手动创建一个。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;编辑&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;.emacs文件，添加如下内容：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;(add-to-list 'load-path "~/.emacs.d")&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;(add-to-list 'load-path "~/.emacs.d/clojure-mode")&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;(require 'clojure-mode)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;其他插件可选择性的安装，关于&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;Emacs插件的安装和配置，这里就不多讲了，大家多Google即可。记住一点，开源东西bug不少，版本兼容性差，大家一定要耐得住性子才能成功啊。坚持，再坚持，哈哈，痛苦的过程。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;推荐安装的插件：&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;auto-complete, paredit,color-theme&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;全部的配置如下&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;(add-to-list&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;load-path&amp;nbsp;"~/.emacs.d")&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(add-to-list&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;load-path&amp;nbsp;"~/.emacs.d/clojure-mode")&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(add-to-list&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;load-path&amp;nbsp;"~/.emacs.d/color-theme")&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(add-to-list&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;load-path&amp;nbsp;"~/.emacs.d/auto-complete")&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;(require&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;clojure-mode)&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;(require&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;color-theme)&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(color-theme-initialize)&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;(color-theme-xemacs)&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;(require&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;auto-complete-config)&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(ac-config-&lt;span style="color: #0000FF;"&gt;default&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;(add-to-list&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;ac-dictionary-directories&amp;nbsp;"~/.emacs.d/auto-complete/dict")&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;(autoload&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;paredit-mode&amp;nbsp;"paredit"&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Minor&amp;nbsp;mode&amp;nbsp;for&amp;nbsp;pseudo-structurally&amp;nbsp;editing&amp;nbsp;Lisp&amp;nbsp;code.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;nbsp;t)&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;emacs-lisp-mode-hook&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(lambda&amp;nbsp;()&amp;nbsp;(paredit-mode&amp;nbsp;+1)))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;lisp-mode-hook&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(lambda&amp;nbsp;()&amp;nbsp;(paredit-mode&amp;nbsp;+1)))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;lisp-interaction-mode-hook&amp;nbsp;(lambda&amp;nbsp;()&amp;nbsp;(paredit-mode&amp;nbsp;+1)))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;scheme-mode-hook&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(lambda&amp;nbsp;()&amp;nbsp;(paredit-mode&amp;nbsp;+1)))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;clojure-mode-hook&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(lambda&amp;nbsp;()&amp;nbsp;(paredit-mode&amp;nbsp;+1)))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;slime-repl-mode-hook&amp;nbsp;(lambda&amp;nbsp;()&amp;nbsp;(paredit-mode&amp;nbsp;+1)))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(defun&amp;nbsp;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;-slime-repl-bindings-with-paredit&amp;nbsp;()&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(define-key&amp;nbsp;slime-repl-mode-map&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(read-kbd-macro&amp;nbsp;paredit-backward-delete-key)&amp;nbsp;nil))&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(add-hook&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;slime-repl-mode-hook&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;-slime-repl-bindings-with-paredit)&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;(custom-&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-variables&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;custom-&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-variables&amp;nbsp;was&amp;nbsp;added&amp;nbsp;by&amp;nbsp;Custom.&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;If&amp;nbsp;you&amp;nbsp;edit&amp;nbsp;it&amp;nbsp;by&amp;nbsp;hand,&amp;nbsp;you&amp;nbsp;could&amp;nbsp;mess&amp;nbsp;it&amp;nbsp;up,&amp;nbsp;so&amp;nbsp;be&amp;nbsp;careful.&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;Your&amp;nbsp;init&amp;nbsp;file&amp;nbsp;should&amp;nbsp;contain&amp;nbsp;only&amp;nbsp;one&amp;nbsp;such&amp;nbsp;instance.&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;If&amp;nbsp;there&amp;nbsp;&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;&amp;nbsp;more&amp;nbsp;than&amp;nbsp;one,&amp;nbsp;they&amp;nbsp;won&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;t&amp;nbsp;work&amp;nbsp;right.&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;(tool-bar-mode&amp;nbsp;nil))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(custom-&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-faces&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;custom-&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-faces&amp;nbsp;was&amp;nbsp;added&amp;nbsp;by&amp;nbsp;Custom.&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;If&amp;nbsp;you&amp;nbsp;edit&amp;nbsp;it&amp;nbsp;by&amp;nbsp;hand,&amp;nbsp;you&amp;nbsp;could&amp;nbsp;mess&amp;nbsp;it&amp;nbsp;up,&amp;nbsp;so&amp;nbsp;be&amp;nbsp;careful.&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;Your&amp;nbsp;init&amp;nbsp;file&amp;nbsp;should&amp;nbsp;contain&amp;nbsp;only&amp;nbsp;one&amp;nbsp;such&amp;nbsp;instance.&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;&amp;nbsp;&amp;nbsp;;;&amp;nbsp;If&amp;nbsp;there&amp;nbsp;&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;&amp;nbsp;more&amp;nbsp;than&amp;nbsp;one,&amp;nbsp;they&amp;nbsp;won&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;t&amp;nbsp;work&amp;nbsp;right.&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;(default&amp;nbsp;((t&amp;nbsp;(:inherit&amp;nbsp;nil&amp;nbsp;:stipple&amp;nbsp;nil&amp;nbsp;:background&amp;nbsp;"gray80"&amp;nbsp;:foreground&amp;nbsp;"black"&amp;nbsp;:inverse-video&amp;nbsp;nil&amp;nbsp;:box&amp;nbsp;nil&amp;nbsp;:strike-through&amp;nbsp;nil&amp;nbsp;:overline&amp;nbsp;nil&amp;nbsp;:underline&amp;nbsp;nil&amp;nbsp;:slant&amp;nbsp;normal&amp;nbsp;:weight&amp;nbsp;normal&amp;nbsp;:height&amp;nbsp;113&amp;nbsp;:width&amp;nbsp;normal&amp;nbsp;:foundry&amp;nbsp;"outline"&amp;nbsp;:family&amp;nbsp;"Consolas")))))&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;&amp;nbsp;(show-paren-mode&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;&amp;nbsp;(setq&amp;nbsp;visible-bell&amp;nbsp;nil)&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;&amp;nbsp;(setq&amp;nbsp;scroll-step&amp;nbsp;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scroll-margin&amp;nbsp;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scroll-conservatively&amp;nbsp;&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;global&lt;/span&gt;-linum-mode&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;linum-mode)&amp;nbsp;;&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-scroll-bar-mode&amp;nbsp;nil)&amp;nbsp;;去掉滚动条&lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;&amp;nbsp;(auto-save-mode&amp;nbsp;nil)&amp;nbsp;;;禁止自动保存&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #0000FF;"&gt;global&lt;/span&gt;-&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;-key&amp;nbsp;(kbd&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C-|&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;other-window);&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;(setq&amp;nbsp;frame-title-format&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;("%S"&amp;nbsp;(buffer-file-name&amp;nbsp;"%f"&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800000;"&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(dired-directory&amp;nbsp;dired-directory&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%b&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;))))&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;5.&lt;span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; "&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;好了，安装完毕，经过一大堆的配置，现在我们要开始享受劳动成果了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;1）&amp;nbsp;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;新建一个文件夹，我用的是&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;D:\new\ClojCodes\&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;2）&amp;nbsp;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;进入终端，输入以下命令：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;cd d: 回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;cd new\ClojCodes\ 回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;lein new Project1回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;3）&amp;nbsp;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;这时，会创建一个&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;D:\new\ClojCodes\ Project1的项目文件夹&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;我们打开这个文件下的&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;project1.clj把内容修改为：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;(defproject&amp;nbsp;SwankProject&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1.0.0-SNAPSHOT&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;:description&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;FIXME:&amp;nbsp;write&amp;nbsp;description&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;:dependencies&amp;nbsp;[[org.clojure/clojure&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1.3.0&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[org.clojure/clojure-contrib&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1.2.0&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;]])&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;保存。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;4）&amp;nbsp;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;终端下进入这个文件夹，输入&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;lein deps回车&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;lein将通过maven的仓库管理，自动下载依赖的jar包并更新&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;可能需要较长时间的等待，请耐心。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;5）&amp;nbsp;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;启动&lt;/span&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;Emacs，打开我们修改过的project1.clj，按下alt+x，Emacs的表示法为M-x，在提示处输入clojure-jack-in，稍候片刻，就会出现slime的repl界面，然后我们可以输入简单的clojure代码进行测试和编程了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="line-height: 115%; font-family: Georgia; font-size: 12pt; "&gt;文章结束，祝大家玩的开心。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9pt; line-height: 115%; font-family: 宋体; "&gt;最后的截图：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9pt; line-height: 115%; font-family: 宋体; "&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://images.cnblogs.com/cnblogs_com/darkluck99/Untitled3.png" width="773" height="598" alt="" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/darkluck99/aggbug/2360216.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/darkluck99/archive/2006/08/08/470688.html</id><title type="text">开张第一日</title><summary type="text">今天终于决心来这里安家了，终于有机会和各位CNBLOGS上的高手一起切磋了，心里那个高兴啊，哈哈哈哈哈哈... ... 其实小弟水平很菜的， 做了2年的Delphi＋SQL Server， 对于.Net还不是很熟， 各位高手有什么经验一定要好好指导我啊！ 我目前对Asp.net的Web 控件开发很感兴趣，希望有这方面经验的朋友给我留言指导，感激涕零啊！ 留下我的MSN：wizzard_cloud@...</summary><published>2006-08-08T01:56:00Z</published><updated>2006-08-08T01:56:00Z</updated><author><name>巫云</name><uri>http://www.cnblogs.com/darkluck99/</uri></author><link rel="alternate" href="http://www.cnblogs.com/darkluck99/archive/2006/08/08/470688.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/darkluck99/archive/2006/08/08/470688.html"/><content type="text">今天终于决心来这里安家了，终于有机会和各位CNBLOGS上的高手一起切磋了，心里那个高兴啊，哈哈哈哈哈哈... ... 其实小弟水平很菜的， 做了2年的Delphi＋SQL Server， 对于.Net还不是很熟， 各位高手有什么经验一定要好好指导我啊！ 我目前对Asp.net的Web 控件开发很感兴趣，希望有这方面经验的朋友给我留言指导，感激涕零啊！ 留下我的MSN：wizzard_cloud@...</content></entry></feed>
