λ演算 (Lambda Calculus) 二 : 柯里化和编码

1. 柯里化(Currying)

柯里化就是把一个多参数的函数转化为单参数函数的方法。类似于复合函数。

现在有两个输入值xy对应一个函数f (x , y),怎么让函数F一开始只接受一个值呢?

我们可以先定义一个 F1 = λx.F2, 然后令 F2 = λy.f (x , y) 完成柯里化。

 

2. 编码(Encoding)

有了这么多运算法则具体能有什么用呢?接下来我们就可以用一些编码来表示编程语言里的基本数据和语句,实现函数式编程。

 

TRUE := λxy.x

FALSE := λxy.y

NOT := λfxy.fyx

OR := λxy.xxy

AND := λxy.xyx

IFELSE := λfxy.fxy

 

计算机的二进制世界里0就是NOT,1就是TRUE。在λ演算中同样如此:

ZERO := λxy.y

 

并且我们有一个加数器,以零为基础每次加一可以得到所有自然数,相对的我们还有减数器每次减一。

SUCCESSOR := λxyz.y(xyz)

PRED := λnfx.n(λgh.h(gf)) (λy.x) (λu.u)

 

以此可以得到一个自然数的通项公式:

n = λfx. f^n (x)

 

还有一些其他的运算法则:

ADD := λxypq.xp(ypq)

MULT := λxyz.x(yz)

EXP := λxy.yx

 

例子:

 NOT TRUE

= (λfxy.fyx) (λxy.x) 
= (λfxy.fyx) (λab.a)
= λxy.(λab.a) yx
= λxy.(λb.y) x
= λxy.y
= FALSE

 

   ONE
= SUCCESSOR ZERO
= (λxyz.y(xyz)) (λxy.y)
= (λxyz.y(xyz)) (λab.b)
= λyz.y((λab.b) yz) 
= λyz.y((λb.b) z) 
= λyz.yz
= ONE

 

    ADD ZERO ONE
= (λxypq.xp(ypq)) (λxy.y) (λxy.xy)
= (λxypq.xp(ypq)) (λab.b) (λcd.cd))
= (λypq. (λab.b) p(ypq)) (λcd.cd))
= (λypq. (λb.b) (ypq)) (λcd.cd))
= (λypq. (ypq)) (λcd.cd))
= (λpq. ((λcd.cd)pq)) 
= (λpq. ((λd.pd)q)) 
= (λpq.pq)) 
= (λxy.xy)
= ONE

 

posted @ 2020-01-07 04:01  IP=PSPACE  阅读(505)  评论(0)    收藏  举报