来源链接 参考:Lambda Calculus in JavaScript
以下是λ-calculus的完整定义。
expression ::= variable
| expression expression
| 𝜆 variable . expression
| ( expression )
这里的定义如图灵机一样简单,有非常丰富的表达能力。简单理解一下,以上定义了一个λ表达式的4种可能的形式:
以下是一些合法的LC(Lambda Calculus)表达式
表达式 | 含义 |
---|---|
𝜆a.b |
输入a,返回b的一个函数。用js的语法可写为 a => b |
𝜆a.b x |
输入a,返回b x 这个表示式的一个函数。b x 表示b(x) 。所以整体是输入a,返回b(x)。a => b(x) |
(𝜆a.b) x |
先定义一个函数a => b,然后用参数x去调用 (a => b)(x) |
𝜆a.𝜆b.a |
输入a,返回𝜆b.a 。a => b => a |
对表达式进行逐步简化的过程,称为β-Reduction
下面测试一下对LC的理解:对如下表达式 ((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
进行 β-Reduction
((𝜆a.a)𝜆b.𝜆c.b)
这一部分,将𝜆b.𝜆c.b
作为a,代入𝜆a.a
,得到 (𝜆b.𝜆c.b)
。整个表达式变为 (𝜆b.𝜆c.b)(x)𝜆e.f
𝜆b.𝜆c.b
,变成 𝜆c.x
。整个表达式变为 (𝜆c.x)𝜆e.f
𝜆e.f
作为c,代入𝜆c.x
,得到x所以,整体表达式化简为x,这时候已经无法再继续化简了,这个叫β-Normal Form
LC里有这样几个著名的算子
算子名 | LC 表示 | JS 表示 | 含义 |
---|---|---|---|
Identity | I := λx.x |
I = x => x |
直接返回输入 |
Mockingbird | Mockingbird := M := ω := λf.ff |
M = f => f(f) |
重复调用两次 |
Kestrel | K := λab.a |
K = a => b => a |
从两个输入里,返回第一个 |
Kite | KI := λab.b |
KI = a => b => b |
从两个输入里,返回第二个 |
Cardinal | Cardinal := C := flip := λfab.fba |
C = f => a => b => f(b)(a) |
将函数的两个参数对调 |
KI
是个有趣的算子,KI
实际上等于K(I)
。将a => a
作为a,代入a => b => a
,得到了 b => (a => a)
。这实际上就是Kite
用函数来定义true/false,可以将 if (x) then ... else ...
看成函数,那true对应的就是 then => else => then
,false对应的就是 then => else => else
T = a => b => a
F = a => b => b
所以其实true就是Kestrel,false就是Kite
由于true/false本身现在是函数,所以NOT可以定义为:
NOT = x => x(F)(T)
x是一个输入的bool值,当其为T时,会选择后面两个参数里的第一个F,当其为F时,会选择T。这就是NOT的行为
所以,可以定义为:
AND = p => q => p(q)(F)
OR = p => q => p(T)(q)
bool 相等的定义:p 和 q
BEQ = p => q => p ( q (T) (F) ) ( q (F) (T) )