来源链接 参考: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) )