λ演算是数理逻辑中的一个形式系统,在函数抽象和应用的基础上,使用变量绑定和替换来表达计算。讨论λ演算离不开形式化的表达。在本文中,咱们尽可能集中在与编程相关的基本概念上,而不拘泥于数学上的形式化表示。λ演算其实是对前面提到的函数概念的简化,方便以系统的方式来研究函数。λ演算的函数有两个重要特征:
函数式编程的λ演算
1、λ演算中的函数都是匿名的,没有显式的名称。好比函数sum(x,y)=x+y能够写成(x,y)|->x+y。因为函数自己仅由其映射关系来肯定,函数名称实际上并无意义。所以使用匿名函数是合理的。
2、λ演算中的函数都只有一个输入。有多个输入的函数能够转换成多个只包含一个输入的函数的嵌套调用。这个过程就是一般所说的柯里化(currying)。如(x,y)|->x+y能够转换成x|->(y|->x+y)。右边的函数的返回值是另一个函数。这一限定简化了λ演算的定义。
对函数简化以后,就能够开始定义λ演算。λ演算是基于λ项(λ-term)的语言。λ项是λ演算的基本单元。λ演算在λ项上定义了各类转换规则。
函数式编程的λ演算
λ项
λ项由下面3个规则来定义:
1、一个变量x自己就是一个λ项。
2、若是M是λ项,x是一个变量,那么(λx.M)也是一个λ项。这样的λ项称为λ抽象(abstraction)。x和M中间的点(.)用来分隔函数参数和内容。
3、若是M和N都是λ项,那么(MN)也是一个λ项。这样的λ项称为应用(application)。
全部的合法λ项,都只能经过重复应用上面的3个规则得来。须要注意的是,λ项最外围的括号是能够省略的,也就是能够直接写为λx.M和MN。当多个λ项链接在一块儿时,须要用括号来进行分隔,以肯定λ项的解析顺序。默认的顺序是左向关联的。因此MNO至关于((MN)O)。在不出现歧义的状况下,能够省略括号。
重复应用上述3个规则就能够获得全部的λ项。把变量做为λ项是重复应用规则的起点。λ项λx.M定义的是匿名函数,把输入变量x的值替换到表达式M中。好比,λx.x+1就是函数f(x)=x+1的λ抽象,其中x是变量,M是x+1。λ项MN表示的是把表达式N应用到函数M上,也就是调用函数。N能够是相似x这样的简单变量,也能够是λ抽象表示的项。当使用λ抽象时,就是咱们一般所说的高阶函数的概念。
函数式编程的λ演算
绑定变量和自由变量
在λ抽象中,若是变量x出如今表达式中,那么该变量被绑定。表达式中绑定变量以外的其余变量称为自由变量。咱们能够用函数的方式来分别定义绑定变量(boundvariable,BV)和自由变量(freevariable,FV)。
对绑定变量来讲:
1、对变量x来讲,BV(x)=∅。也就是说,一个单独的变量是自由的。
2、对λ项M和变量x来讲,BV(λx.M)=BV(M)∪{x}。也就是说,λ抽象在M中已有的绑定变量的基础上,额外绑定了变量x。
3、对λ项M和λ项N来讲,BV(MN)=BV(M)∪BV(N)。也就是说,λ项的应用结果中的绑定变量的集合是各自λ项的绑定变量集合的并集。
对自由变量来讲,相应的定义和绑定变量是相反的:
1、对变量x来讲,FV(x)={x}。
2、对λM和变量x来讲,FV(λx.M)=FV(M)−{x}。
3、对λ项M和λ项N来讲,FV(MN)=FV(M)∪FV(N)。
在λ项λx.x+1中,x是绑定变量,没有自由变量。在λ项λx.x+y中,x是绑定变量,y是自由变量。
在λ抽象中,绑定变量的名称在某些状况下是可有可无的。如λx.x+1和λy.y+1实际上表示的是一样的函数,都是把输入值加1。变量名称x或y,并不影响函数的语义。相似λx.x+1和λy.y+1这样的λ项在λ演算中被认为是相等的,称为α等价(alphaequivalence)。