﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-justinlei-文章分类-Scheme</title><link>http://www.blogjava.net/justinlei/category/3750.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 03 Mar 2007 02:46:50 GMT</lastBuildDate><pubDate>Sat, 03 Mar 2007 02:46:50 GMT</pubDate><ttl>60</ttl><item><title>Lambda表达式基础</title><link>http://www.blogjava.net/justinlei/articles/15093.html</link><dc:creator>JustinLei</dc:creator><author>JustinLei</author><pubDate>Sun, 09 Oct 2005 15:03:00 GMT</pubDate><guid>http://www.blogjava.net/justinlei/articles/15093.html</guid><wfw:comment>http://www.blogjava.net/justinlei/comments/15093.html</wfw:comment><comments>http://www.blogjava.net/justinlei/articles/15093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/justinlei/comments/commentRss/15093.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/justinlei/services/trackbacks/15093.html</trackback:ping><description><![CDATA[      1 #! /usr/bin/guile -s-
      2 !#-
      3 -
      4 -
      5 #!-
      6 这是一个参数的Lambda加法-
      7 !#-
      8 (display ((lambda (x) (+ x x))1))(newline) -
      9 -
     10 #!-
     11 这是两个参数的Lambda减法-
     12 !#-
     13 (define reverse-subtract-
     14   (lambda (x y) (- y x)))-
     15 (display (reverse-subtract 7 10 ))(newline)-
     16 -
     17 #!-
     18 带有局部变量的两个参数的Lambda加法-
     19 !#-
     20 (define foo-
     21   (let ((x 4))-
     22     (lambda (y) (+ x y))))-
     23 (display (foo 6))(newline)-
<img src ="http://www.blogjava.net/justinlei/aggbug/15093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/justinlei/" target="_blank">JustinLei</a> 2005-10-09 23:03 <a href="http://www.blogjava.net/justinlei/articles/15093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>λ演算</title><link>http://www.blogjava.net/justinlei/articles/14985.html</link><dc:creator>JustinLei</dc:creator><author>JustinLei</author><pubDate>Sat, 08 Oct 2005 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/justinlei/articles/14985.html</guid><wfw:comment>http://www.blogjava.net/justinlei/comments/14985.html</wfw:comment><comments>http://www.blogjava.net/justinlei/articles/14985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/justinlei/comments/commentRss/14985.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/justinlei/services/trackbacks/14985.html</trackback:ping><description><![CDATA[<p><b>λ演算</b>是一套用于研究<a href="http://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0" title="函数">函数</a>定义、函数应用和<a href="http://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92" title="递归">递归</a>的<a href="http://zh.wikipedia.org/w/index.php?title=%E5%BD%A2%E5%BC%8F%E7%B3%BB%E7%BB%9F&amp;action=edit" class="new" title="形式系统">形式系统</a>。它由 <a href="http://zh.wikipedia.org/w/index.php?title=Alonzo_Church&amp;action=edit" class="new" title="Alonzo Church">Alonzo Church</a> 和 <a href="http://zh.wikipedia.org/w/index.php?title=Stephen_Cole_Kleene&amp;action=edit" class="new" title="Stephen Cole Kleene">Stephen Cole Kleene</a> 在 20 世纪三十年代引入，Church 运用 lambda 演算在 1936 年给出 <a href="http://zh.wikipedia.org/w/index.php?title=%E5%88%A4%E5%AE%9A%E6%80%A7%E9%97%AE%E9%A2%98&amp;action=edit" class="new" title="判定性问题">判定性问题</a> (Entscheidungsproblem) 的一个否定的答案。这种演算可以用来清晰地定义什么是一个<a href="http://zh.wikipedia.org/w/index.php?title=%E5%8F%AF%E8%AE%A1%E7%AE%97%E5%87%BD%E6%95%B0&amp;action=edit" class="new" title="可计算函数">可计算函数</a>。关于两个 lambda 演算表达式是否等价的命题无法通过一个通用的算法来解决，这是不可判定性能够证明的头一个问题，甚至还在<a href="http://zh.wikipedia.org/w/index.php?title=%E5%81%9C%E6%9C%BA%E9%97%AE%E9%A2%98&amp;action=edit" class="new" title="停机问题">停机问题</a>之先。Lambda 演算对<a href="http://zh.wikipedia.org/w/index.php?title=%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B&amp;action=edit" class="new" title="函数式编程">函数式编程</a>有巨大的影响，特别是<a href="http://zh.wikipedia.org/wiki/Lisp" title="Lisp">Lisp 语言</a>。</p>

<p>Lambda 演算可以被称为最小的通用程序设计语言。它包括一条变换规则 (变量替换) 和一条函数定义方式，Lambda 演算之通用在于，任何一个可计算函数都能用这种形式来表达和求值。因而，它是等价于<a href="http://zh.wikipedia.org/wiki/%E5%9B%BE%E7%81%B5%E6%9C%BA" title="图灵机">图灵机</a>的。尽管如此，Lambda 演算强调的是变换规则的运用，而非实现它们的具体机器。可以认为这是一种更接近软件而非硬件的方式。<br>
</p>
<h2>历史</h2>

<p>最开始，Church 试图创制一套完整的形式系统作为数学的基础，当他发现这个系统易受<a href="http://zh.wikipedia.org/wiki/%E7%BD%97%E7%B4%A0%E6%82%96%E8%AE%BA" title="罗素悖论">罗素悖论</a>的影响时，就把 lambda 演算单独分离出来，用于研究<a href="http://zh.wikipedia.org/wiki/%E5%8F%AF%E8%AE%A1%E7%AE%97%E6%80%A7" title="可计算性">可计算性</a>，最终导致了他对<a href="http://zh.wikipedia.org/w/index.php?title=%E5%88%A4%E5%AE%9A%E6%80%A7%E9%97%AE%E9%A2%98&amp;action=edit" class="new" title="判定性问题">判定性问题</a>的否定回答。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=2" title="Λ演算">编辑</a>]</div>

<p><a name=".E9.9D.9E.E5.BD.A2.E5.BC.8F.E5.8C.96.E7.9A.84.E6.8F.8F.E8.BF.B0"></a></p>

<h2>非形式化的描述</h2>

<p>在 lambda
演算中，每个表达式都代表一个只有单独参数的函数，这个函数的参数本身也是一个只有单一参数的函数，同时，函数的值是又一个只有单一参数的函数。函数是通
过 lambda 表达式匿名地定义的，这个表达式说明了此函数将对其参数进行什么操作。例如，“加 2”函数 <i>f</i>(<i>x</i>) = <i>x</i> + 2 可以用 lambda 演算表示为 λ <i>x</i>. <i>x</i> + 2 (λ <i>y</i>. <i>y</i> + 2 也是一样的，参数的取名无关紧要) 而 <i>f</i>(3) 的值可以写作 (λ <i>x</i>. <i>x</i> + 2) 3。函数的作用 (application) 是<a href="http://zh.wikipedia.org/w/index.php?title=%E5%B7%A6%E7%BB%93%E5%90%88&amp;action=edit" class="new" title="左结合">左结合</a>的：<i>f</i> <i>x</i> <i>y</i> = (<i>f</i> <i>x</i>) <i>y</i>。考虑这么一个函数：它把一个函数作为参数，这个函数将被作用在 3 上：λ <i>x</i>. <i>x</i> 3。如果把这个 (用函数作参数的) 函数作用于我们先前的“加 2”函数上：(λ <i>x</i>. <i>x</i> 3) (λ <i>x</i>. <i>x</i>+2)，则明显地，下述三个表达式：</p>

<dl>
<dd>(λ <i>x</i>. <i>x</i> 3) (λ <i>x</i>. <i>x</i>+2)&nbsp;&nbsp; 与 &nbsp;&nbsp; (λ <i>x</i>. <i>x</i> + 2) 3 &nbsp;&nbsp; 与 &nbsp;&nbsp; 3 + 2</dd>
</dl>

<p>是等价的。有两个参数的函数可以通过 lambda 演算这么表达：一个单一参数的函数的返回值又是一个单一参数的函数 (参见 <a href="http://zh.wikipedia.org/w/index.php?title=Currying&amp;action=edit" class="new" title="Currying">Currying</a>)。例如，函数 <i>f</i>(<i>x</i>, <i>y</i>) = <i>x</i> - <i>y</i> 可以写作 λ <i>x</i>. λ <i>y</i>. <i>x</i> - <i>y</i>。下述三个表达式：</p>

<dl>
<dd>(λ <i>x</i>. λ <i>y</i>. <i>x</i> - <i>y</i>) 7 2 &nbsp;&nbsp; 与 &nbsp;&nbsp; (λ <i>y</i>. 7 - <i>y</i>) 2 &nbsp;&nbsp; 与 &nbsp;&nbsp; 7 - 2</dd>
</dl>

<p>也是等价的。然而这种 lambda 表达式之间的等价性无法找到一个通用的函数来判定。</p>

<p>并非所有的 lambda 表达式都可以规约至上述那样的确定值，考虑</p>

<dl>
<dd>(λ <i>x</i>. <i>x</i> <i>x</i>) (λ <i>x</i>. <i>x</i> <i>x</i>)</dd>
</dl>

<p>或</p>

<dl>
<dd>(λ <i>x</i>. <i>x</i> <i>x</i> <i>x</i>) (λ <i>x</i>. <i>x</i> <i>x</i> <i>x</i>)</dd>
</dl>

<p>然后试图把第一个函数作用在它的参数上。 (λ <i>x</i>. <i>x</i> <i>x</i>) 被称为 ω <a href="http://zh.wikipedia.org/w/index.php?title=%E7%BB%84%E5%90%88%E5%AD%90&amp;action=edit" class="new" title="组合子">组合子</a> (combinator)，((λ <i>x</i>. <i>x</i> <i>x</i>) (λ <i>x</i>. <i>x</i> <i>x</i>)) 被称为 Ω，而 ((λ <i>x</i>. <i>x</i> <i>x</i> <i>x</i>) (λ <i>x</i>. <i>x</i> <i>x</i> <i>x</i>)) 被称为 Ω<sub>2</sub>，以此类推。</p>

<p>若仅形式化函数作用的注记而不允许 lambda 表达式，就得到了<a href="http://zh.wikipedia.org/w/index.php?title=%E7%BB%84%E5%90%88%E5%AD%90%E9%80%BB%E8%BE%91&amp;action=edit" class="new" title="组合子逻辑">组合子逻辑</a> (combinatory logic)。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=3" title="Λ演算">编辑</a>]</div>

<p><a name=".E5.BD.A2.E5.BC.8F.E5.8C.96.E5.AE.9A.E4.B9.89"></a></p>

<h2>形式化定义</h2>

<p>形式化地，我们从一个标识符 (identifier) 的<a href="http://zh.wikipedia.org/wiki/%E5%8F%AF%E6%95%B0%E6%97%A0%E7%A9%B7" title="可数无穷">可数无穷</a><a href="http://zh.wikipedia.org/wiki/%E9%9B%86%E5%90%88" title="集合">集合</a>开始，比如 {a, b, c, ..., x, y, z, x<sub>1</sub>, x<sub>2</sub>, ...}，则所有的 lambda 表达式可以通过下述以 <a href="http://zh.wikipedia.org/wiki/%E5%B7%B4%E7%A7%91%E6%96%AF%E8%8C%83%E5%BC%8F" title="巴科斯范式">BNF</a> 范式表达的<a href="http://zh.wikipedia.org/wiki/%E4%B8%8A%E4%B8%8B%E6%96%87%E6%97%A0%E5%85%B3%E6%96%87%E6%B3%95" title="上下文无关文法">上下文无关文法</a>描述：</p>

<ol>
<li>&lt;expr&gt;&nbsp;::= &lt;identifier&gt;</li><li>&lt;expr&gt;&nbsp;::= (λ &lt;identifier&gt; . &lt;expr&gt;)</li><li>&lt;expr&gt;&nbsp;::= (&lt;expr&gt; &lt;expr&gt;)</li>
</ol>

<p>头两条规则用来生成函数，而第三条描述了函数是如何作用在参数上的。通常，lambda 抽象 (规则 2) 和函数作用 (规则 3)
中的括号在不会产生歧义的情况下可以省略。如下假定保证了不会产生歧义：(1) 函数的作用是左结合的，和 (2) lambda
操作符被绑定到它后面的整个表达式。例如，表达式 ((λ <i>x</i>. (<i>x</i> <i>x</i>)) (λ <i>y</i>. <i>y</i>)) 可以简写成 (λ <i>x</i>. <i>x</i> <i>x</i>) λ <i>y</i>.<i>y</i>。</p>

<p>类似 λ <i>x</i>. (<i>x</i> <i>y</i>) 这样的 lambda 表达式并未定义一个函数，因为变元 <i>y</i> 的出现是<i>自由</i>的，即它并没有被<i>绑定</i>到表达式中的任何一个 λ 上。变元出现次数的绑定是通过下述规则 (基于 lambda 表达式的结构<a href="http://zh.wikipedia.org/w/index.php?title=%E5%BD%92%E7%BA%B3&amp;action=edit" class="new" title="归纳">归纳</a>地) 定义的：</p>

<ol>
<li>在表达式 <i>V</i> 中，<i>V</i> 是变元，则这个表达式里变元 <i>V</i> 只有一次自由出现。</li><li>在表达式 λ <i>V</i> . <i>E</i> 中 (<i>V</i> 是变元，<i>E</i> 是另一个表达式)，变元自由出现的次数是 <i>E</i> 中变元自由出现的次数，减去 <i>E</i> 中 <i>V</i> 自由出现的次数。因而，<i>E</i> 中那些 <i>V</i> 被称为绑定在 λ 上。</li><li>在表达式 (<i>E</i> <i>E'</i> ) 中，变元自由出现的次数是 <i>E</i> 和 <i>E'</i> 中变元自由出现次数之和。</li>
</ol>

<p>在 lambda 表达式的集合上定义了一个<a href="http://zh.wikipedia.org/wiki/%E7%AD%89%E4%BB%B7%E5%85%B3%E7%B3%BB" title="等价关系">等价关系</a> (在此用 == 标注)，“两个表达式其实表示的是同一个函数”这样的直觉性判断即由此表述，这种等价关系是通过所谓的“alpha-变换规则”和“beta-消解规则”。</p>

<p><br></p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=4" title="Λ演算">编辑</a>]</div>

<p><a name=".CE.B1-.E5.8F.98.E6.8D.A2"></a></p>

<h3>α-变换</h3>

<p>Alpha-变换规则表达的是，被绑定变量的名称是不重要的。比如说 λ<i>x</i>.<i>x</i> 和 λ<i>y</i>.<i>y</i> 是同一个函数。尽管如此，这条规则并非像它看起来这么简单，关于被绑定的变量能否由另一个替换有一系列的限制。</p>

<p>Alpha-变换规则陈述的是，若 <i>V</i> 与 <i>W</i> 均为变元，<i>E</i> 是一个 lambda 表达式，同时 <i>E</i>[<i>V</i>/<i>W</i>] 是指把表达式 <i>E</i> 中的所有的 <i>V</i> 的自由出现都替换为 <i>W</i>，那么在 <i>W</i> 不是 <i>E</i> 中的一个自由出现，且如果 <i>W</i> 替换了 <i>V</i>，<i>W</i> 不会被 <i>E</i> 中的 λ 绑定的情况下，有</p>

<dl>
<dd>λ <i>V</i>. <i>E</i> == λ <i>W</i>. <i>E</i>[<i>V</i>/<i>W</i>]</dd>
</dl>

<p>这条规则告诉我们，例如 λ <i>x</i>. (λ <i>x</i>. <i>x</i>) <i>x</i> 这样的表达式和 λ <i>y</i>. (λ <i>x</i>. <i>x</i>) <i>y</i> 是一样的。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=5" title="Λ演算">编辑</a>]</div>

<p><a name=".CE.B2-.E6.B6.88.E8.A7.A3"></a></p>

<h3>β-消解</h3>

<p>Beta-消解规则表达的是函数作用的概念。它陈述了若所有的 <i>E'</i> 的自由出现在 <i>E</i> [<i>V</i>/<i>E'</i> ] 中仍然是自由的情况下，有</p>

<dl>
<dd>((λ <i>V</i>. <i>E</i> ) <i>E'</i> ) == <i>E</i> [<i>V</i>/<i>E'</i> ]</dd>
</dl>

<p>成立。</p>

<p>== 关系被定义为满足上述两条规则的最小等价关系 (即在这个等价关系中减去任何一个映射，它将不再是一个等价关系)。</p>

<p>对上述等价关系的一个更具操作性的定义可以这样获得：只允许从左至右来应用规则。不允许任何 beta 消解的 lambda 表达式被称为<i>范式</i>。
并非所有的 lambda
表达式都存在与之等价的范式，若存在，则对于相同的形式参数命名而言是唯一的。此外，有一个算法用户计算范式，不断地把最左边的形式参数替换为实际参数，
直到无法再作任何可能的消解为止。这个算法当且仅当 lambda 表达式存在一个范式时才会停止。<a href="http://zh.wikipedia.org/w/index.php?title=Church-Rosser_%E5%AE%9A%E7%90%86&amp;action=edit" class="new" title="Church-Rosser 定理">Church-Rosser 定理</a> 说明了，当且仅当两个表达式等价时，它们会在形式参数换名后得到同一个范式。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=6" title="Λ演算">编辑</a>]</div>

<p><a name=".CE.B7-.E5.8F.98.E6.8D.A2"></a></p>

<h3>η-变换</h3>

<p>前两条规则之后，还可以加入第三条规则，eta-变换，来形成一个新的等价关系。Eta-变换表达的是<a href="http://zh.wikipedia.org/w/index.php?title=%E5%A4%96%E5%BB%B6%E6%80%A7&amp;action=edit" class="new" title="外延性">外延性</a>的概念，在这里外延性指的是，两个函数对于所有的参数得到的结果都一致，当且仅当它们是同一个函数。Eta-变换可以令 λ <i>x</i> . <i>f</i> <i>x</i> 和 <i>f</i> 相互转换，只要 <i>x</i> 不是 <i>f</i> 中的自由出现。下面说明了为何这条规则和外延性是等价的：</p>

<p>若 <i>f</i> 与 <i>g</i> 外延地等价，即，<i>f</i> <i>a</i> == <i>g</i> <i>a</i> 对所有的 lambda 表达式 <i>a</i> 成立，则当取 <i>a</i> 为在 <i>f</i> 中不是自由出现的变量 <i>x</i> 时，我们有 <i>f</i> <i>x</i> == <i>g</i> <i>x</i>，因此 λ <i>x</i> . <i>f</i> <i>x</i> == λ <i>x</i> . <i>g</i> <i>x</i>，由 eta-变换 <i>f</i> == <i>g</i>。所以只要 eta-变换是有效的，会得到外延性也是有效的。</p>

<p>相反地，若外延性是有效的，则由 beta-消解，对所有的 <i>y</i> 有 (λ <i>x</i> . <i>f</i> <i>x</i>) <i>y</i> == <i>f</i> <i>y</i>，可得 λ <i>x</i> . <i>f</i> <i>x</i> == <i>f</i>，即 eta-变换也是有效的。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=7" title="Λ演算">编辑</a>]</div>

<p><a name="lambda_.E6.BC.94.E7.AE.97.E4.B8.AD.E7.9A.84.E8.BF.90.E7.AE.97" id="lambda_.E6.BC.94.E7.AE.97.E4.B8.AD.E7.9A.84.E8.BF.90.E7.AE.97"></a></p>

<h2>lambda 演算中的运算</h2>

<p>在 lambda 演算中有许多方式都可以定义<a href="http://zh.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E6%95%B0" title="自然数">自然数</a>，但最常见的还是<a href="http://zh.wikipedia.org/w/index.php?title=Church_%E6%95%B4%E6%95%B0&amp;action=edit" class="new" title="Church 整数">Church 整数</a>，下面是它们的定义：</p>

<dl>
<dd>0 = λ <i>f</i>. λ <i>x</i>. <i>x</i></dd><dd>1 = λ <i>f</i>. λ <i>x</i>. <i>f</i> <i>x</i></dd><dd>2 = λ <i>f</i>. λ <i>x</i>. <i>f</i> (<i>f</i> <i>x</i>)</dd><dd>3 = λ <i>f</i>. λ <i>x</i>. <i>f</i> (<i>f</i> (<i>f</i> <i>x</i>))</dd>
</dl>

<p>以此类推。直观地说，lambda 演算中的数字 <i>n</i> 就是一个把函数 <i>f</i> 作为参数并以 <i>f</i> 的 <i>n</i> 次幂为返回值的函数。换句话说，Church 整数是一个<a href="http://zh.wikipedia.org/w/index.php?title=%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0&amp;action=edit" class="new" title="高阶函数">高阶函数</a> -- 以单一参数函数 <i>f</i> 为参数，返回另一个单一参数的函数。</p>

<p>(注意在 Church 原来的 lambda 演算中，lambda 表达式的形式参数在函数体中至少出现一次，这使得我们无法像上面那样定义 0) 在 Church 整数定义的基础上，我们可以定义一个后继函数，它以 <i>n</i> 为参数，返回 <i>n</i> + 1：</p>

<dl>
<dd>SUCC = λ <i>n</i>. λ <i>f</i>. λ <i>x</i>. <i>f</i> (<i>n</i> <i>f</i> <i>x</i>)</dd>
</dl>

<p>加法是这样定义的：</p>

<dl>
<dd>PLUS = λ <i>m</i>. λ <i>n</i>. λ <i>f</i>. λ <i>x</i>. <i>m</i> <i>f</i> (<i>n</i> <i>f</i> <i>x</i>)</dd>
</dl>

<p>PLUS 可以被看作以两个自然数为参数的函数，它返回的也是一个自然数。你可以试试验证</p>

<dl>
<dd>PLUS 2 3 &nbsp;&nbsp; 与 &nbsp;&nbsp; 5</dd>
</dl>

<p>是否等价。乘法可以这样定义：</p>

<dl>
<dd>MULT = λ <i>m</i>. λ <i>n</i>. <i>m</i> (PLUS <i>n</i>) 0,</dd>
</dl>

<p>即 <i>m</i> 乘以 <i>n</i> 等于在零的基础上 <i>n</i> 次加 <i>m</i>。另一种方式是</p>

<dl>
<dd>MULT = λ <i>m</i>. λ <i>n</i>. λ <i>f</i>. <i>m</i> (<i>n</i> <i>f</i>)</dd>
</dl>

<p>正整数 <i>n</i> 的前驱元 (predecessesor) PRED <i>n</i> = <i>n</i> - 1 要复杂一些：</p>

<dl>
<dd>PRED = λ <i>n</i>. λ <i>f</i>. λ <i>x</i>. <i>n</i> (λ <i>g</i>. λ <i>h</i>. <i>h</i> (<i>g</i> <i>f</i>)) (λ <i>u</i>. <i>x</i>) (λ <i>u</i>. <i>u</i>)</dd>
</dl>

<p>或者</p>

<dl>
<dd>PRED = λ <i>n</i>. <i>n</i> (λ <i>g</i>. λ <i>k</i>. (<i>g</i> 1) (λ <i>u</i>. PLUS (<i>g</i> <i>k</i>) 1) <i>k</i>) (λ <i>l</i>. 0) 0</dd>
</dl>

<p>注意 (<i>g</i> 1) (λ <i>u</i>. PLUS (<i>g</i> <i>k</i>) 1) <i>k</i> 表示的是，当 <i>g</i>(1) 是零时，表达式的值是 <i>k</i>，否则是 <i>g</i>(<i>k</i>) + 1。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=8" title="Λ演算">编辑</a>]</div>

<p><a name=".E9.80.BB.E8.BE.91.E4.B8.8E.E6.96.AD.E8.A8.80"></a></p>

<h2>逻辑与断言</h2>

<p>习惯上，下述两个定义 (称为 Church 布尔值) 被用作 TRUE 和 FALSE 这样的布尔值：</p>

<dl>
<dd>TRUE = λ <i>u</i>. λ <i>v</i>. <i>u</i></dd><dd>FALSE = λ <i>u</i>. λ <i>v</i>. <i>v</i></dd>
</dl>

<p><i>断言</i>是指返回布尔值的函数。最基本的一个断言 ISZERO，当且仅当其参数为零时返回真：</p>

<dl>
<dd>ISZERO = λ <i>n</i>. <i>n</i> (λ <i>x</i>. FALSE) TRUE</dd>
</dl>

<p>断言的运用与上述 TRUE 和 FALSE 的定义，使得 "if-then-else" 这类语句很容易用 lambda 演算写出。</p>

<div class="editsection" style="float: right; margin-left: 5px;">[<a href="http://zh.wikipedia.org/w/index.php?title=%CE%9B%E6%BC%94%E7%AE%97&amp;action=edit&amp;section=9" title="Λ演算">编辑</a>]</div>

<p><a name=".E9.81.9E.E6.AD.B8"></a></p>

<h2>递归</h2>

<p><a href="http://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92" title="递归">递归</a>是一种以函数自身迭代自身变元的算法，一般是通过函数自身来定义函数的方式实现。表面看来 lambda 演算不允许递归，其实这是一种对递归的误解。考虑<a href="http://zh.wikipedia.org/wiki/%E9%9A%8E%E4%B9%98" title="階乘">阶乘</a>函数 <i>f</i>(<i>n</i>) 一般这样递归地定义：</p>

<dl>
<dd><i>f</i>(<i>n</i>) = 1, 若 <i>n</i> = 0; <i>n</i>·<i>f</i>(<i>n</i>-1), 若 <i>n</i>&gt;0.</dd>
</dl>

<p>λ语言：</p>

<dl>
<dd>FACT = λ <i>n</i>. <i>n</i> (λ <i>u</i>. MULT <i>n</i> (FACT (PRED <i>n</i>))) 1</dd>
</dl>

<p>用 Y-组合子 在 λ语言 中合法地定义：</p>

<dl>
<dd>FACT = Y (λ <i>g</i>. λ <i>n</i>. <i>n</i> (λ <i>u</i>. MULT <i>n</i> (<i>g</i> (PRED <i>n</i>))) 1)</dd>
</dl>

<dl>
<dd>Y = λ <i>f</i>. ((λ <i>x</i>. <i>f</i> (<i>x</i> <i>x</i>)) (λ <i>x</i>. <i>f</i> (<i>x</i> <i>x</i>)))</dd>
</dl>
<img src ="http://www.blogjava.net/justinlei/aggbug/14985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/justinlei/" target="_blank">JustinLei</a> 2005-10-08 14:49 <a href="http://www.blogjava.net/justinlei/articles/14985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>