(一)
这里先不列出λ项的正式定义,只记住λ表达式语义上的构造方式为:
  1. x
一个单独的变量名是一个λ项表达式;
  1. (λx.M)
该λ表示一个函数。其中 M 是这个函数的函数体,M 本身也是一个 λ项。
除了 x 之外,M 中可能还有其他变量名,λ 这个符号用于指示函数体 M 的参数为 x。
了便于理解,可以将 M 看作函数体,x 看作形参,即变量名。
 
例如:λx.x+3 即表示一个函数 f(x) = x+3,该函数会返回x与3相加的结果
要注意的是,我这里的写法并不规范,在λ表达式中,二元运算符是作为前缀的。x+3 应该写作 (+ x 3)。所以这个表达式的正规写法是 λx.(+ x 3)。至于为什么,我们之后再讲。
  1. (M N)
其中 M,N 均为λ项表达式。
如果 M 本身是一个函数,我们说将函数 M 应用于 N。如果 M 不是函数,不接受参数,N 将在求值的过程中被忽略。
例如:(λx.(+ x 3) 4),其中M为表达式 λx.x+3,N 为 4。这个表达式表示将函数应用于 4,即f(4) 
 
所以一个典型的λ表达式具有如下形式:
 (λx.M) N,为了方便去掉括号写作 λx.M N
 
其中 M 是函数体,x 可以看作形参,即变量名, N 可以看作实参,即变量值。
 
函数本身也可以作为参数,例如(λx.x)(λx.(+x 3)),  表达式左边就是一个函数,这个函数将返回它自己的参数,将这个函数应用于我们之前说的函数 f,参数是 f,那么这个函数将返回 f。
 
如此一来,第一种形式的λ表达式代表一个变量;
第二种表达式代表一个函数;
第三种表达式则代表将函数应用于一个值,即一次函数调用。
 
(二)归约
第一种表达式的值即它本身;
第二种表达式的值表示这个函数本身;
因此,在讨论求值时,我们只关心第三种,即将一个函数应用于另一个λ表达式时,如何计算它的值。
 
如上所述,λ表达式的应用等效于一次函数调用。我们知道,调用函数的时候,会将所有的形参替换用实参的值,并返回计算结果。因此,我们说在表达式 λx.M N 中,函数体 M 里的 x 与表达式 N 绑定,M 中剩下未绑定的变量则是自由变量。
 
对 λx.M N 进行求值时,M 中所有的 x 都将被替换为 N。这一过程称为归约,归约后得到简化的λ表达式,可以进一步归约直至无法再归约,此时的表达式就是对原表达式进行求值的结果。
 
考虑一个函数 f(x)=x+3,写作λ表达式就是 (λx.(+x 3))。
如前所述,当我们想计算 f(4) 时,将函数应用于 4,表达式为 λx.(+ x 3) 4。
按照归约的法则,函数体 (+ x 3) 中的 x 被 4 替换,函数表达式变为 (+ 4 3),结果为 7。
 
考虑另一个函数 g(y)=y*2,λ表达式 λy.(* y 2)。
如果我们想将函数 g 应用于 f(4) 的计算结果,即 g(f(4)),我们可以将 g 的λ表达式应用于上述表达式,即 λy.(* y 2)  (λx.(+ x 3) 4)
 
然后我们进行归约,这里有两种归约顺序。
 
一种是同之前一样,先计算右边表达式的值,即归约为 λy.(* y 2) 7。
然后将函数体 (* y 2) 中的 y 替换为 7,得到 (* 7 2)。
最终结果是 14。
 
另一种归约顺序是先计算最外层的应用,即将y替换为右边的表达式(λx.(+ x 3) 4),得到归约后的表达式(* (λx.(+ x 3) 4) 2)。
再归约内层的应用,替换 x 得到 (* (+ 4 3) 2)。
最终结果为(* 7 2)=14。
 
在这个例子中,不同的归约顺序得出了相同的结果,然而,这并不是普遍现象。这里面暗藏了一个计算机程序中常见的概念:作用域。
 
 

Lambda演算(二)归约!归约!归约!的更多相关文章

  1. 简单易懂的程序语言入门小册子(1.5):基于文本替换的解释器,递归定义与lambda演算的一些额外说明

    这一篇接在第一篇lambda演算的后面.讲讲一些数学知识. 经常有些看似很容易理解的东西,一旦要描述得准确无误,就会变得极为麻烦. 软件工程里也有类似情况:20%的代码实现了核心功能,剩下80%的代码 ...

  2. Lambda演算(一)大道至简

    从选择信息专业开始到回炉读书为止,四舍五入码了八年代码.对于计算机科学的认知仅限于: 1)使用不同语言实现特定功能 2)实现不同算法以增进系统性能 3)搭建不同架构进行组织管理   但从未思考一些本质 ...

  3. [学习] 从 函数式编程 到 lambda演算 到 函数的本质 到 组合子逻辑

    函数式编程 阮一峰 <函数式编程初探>,阮一峰是<黑客与画家>的译者. wiki <函数编程语言> 一本好书,<计算机程序的构造与解释>有讲到schem ...

  4. 简单易懂的程序语言入门小册子(1):基于文本替换的解释器,lambda演算

    最近比较闲,打算整理一下之前学习的关于程序语言的知识.主要的内容其实就是一边设计程序语言一边写解释器实现它.这些知识基本上来自Programming Languages and Lambda Calc ...

  5. lambda演算

    先了解下相关的知识点(以下都只用先了解简单的概念,建议wiki): BNF范式,上下文无关文法,函数柯里化. lambda读书笔记演算: http://www.blogjava.net/wxb_nud ...

  6. Lambda演算 - 简述Y组合子的作用

    Y组合子:\f.(\x.f(xx))(\x.f(xx)),接受一个函数,返回一个高阶函数 Y组合子用于生成匿名递归函数. 什么叫匿名递归函数,考虑以下C语言递归函数 int sum(int n) { ...

  7. [摘录] 图灵机与lambda演算的关系

    在阅读函数式编程相关资料时,看到如下一段话.感觉说的很好,可以帮助我这种学渣一点点的建立起整个知识体系. 以下片段,摘抄自豆瓣网友 赛义甫 的豆列 “逻辑与计算” 中的一段介绍. 莱布尼兹曾经有两个梦 ...

  8. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  9. 我的最爱Lambda演算——开篇

    (在这个帖子的原始版本里,我试图用一个JavaScript工具来生成MathML.但不太顺利:有几个浏览器没法正确的渲染,在RSS feed里也显示的不好.所以我只好从头开始,用简单的文本格式重新写一 ...

随机推荐

  1. 国内各运营商(ISP)IP段表

    国内各运营商(ISP)IP段表 来源:http://bbs.hh010.com/forum.php?mod=viewthread&tid=490529&orderby=dateline ...

  2. 一张图彻底搞懂JavaScript的==运算

    一张图彻底搞懂JavaScript的==运算 来源 https://zhuanlan.zhihu.com/p/21650547 PS:最后,把图改了一下,仅供娱乐 : ) 大家知道,==是JavaSc ...

  3. [Leetcode] Symmetric tree 对称二叉树

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  4. BZOJ1452 [JSOI2009]Count 【树套树 (树状数组)】

    1452: [JSOI2009]Count Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 2693  Solved: 1574 [Submit][St ...

  5. readelf用法小记

    By francis_hao    Feb 14,2017 显示ELF文件的信息 用法概述 readelf和objdump类似,不过,readelf会显示更详细的信息,而且独立于BFD库,因此当BFD ...

  6. SCOI2008奖励关 [状压dp]

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  7. webstorm中把style的内容隐藏,如何把style的内容展开?

    我们经常看到在webstorm中style的内容以...表示如下图所示,只有把光标移到上面时才会看到内容: 如何把上述的style的内容展开呢? 请按一下步骤操作: 第一步:File------> ...

  8. zigbee ---- profile 和 cluster

    在zigbee规范中,引入了profile, cluster的概念.具体说来,假设规范一个profile(可以理解成一套规定),这个profile用来规范智能家居领域的相关产品都要满足那些要求,那么h ...

  9. 普通table表格样式及代码大全

     普通table表格样式及代码大全(全)(一) 单实线边框表格 <table style="border-collapse: collapse" borderColor=#0 ...

  10. ES6学习笔记(一)——Promise

    Promise 是 ES6 提供的一种异步编程的解决方案: 将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数(解决异步函数回调地狱的问题).Promise 对象保存着异步操作的结果. 首先 ...