Scarlet Serenade

Computation | Lambda Calculus | Encoding

Encoding Boolean

let cond p a b = if p then a else b 是常见的 boolean 操作,我们从这个方法下手。可以看出如果将 a b 看作一个 tuple 那么 p 就像一个一个从 tuple 中取值的函数。true 为取第一个元素,false 为第二个。 容易写出函数表达的 boolean:

let true' a b = a

let false' a b = b

let and' a b = a b false'

let or' a b = a true' b
COND == λpab.p a b
TRUE == λx.λy.x
FALSE == λx.λy.y

AND == λab.a b FALSE
OR == λab.a TRUE b

Encoding Pairs

Using booleans, we can encode pairs of values as terms.

construct_pair = λf. λs. λb. b f s 
fst = λp. p true
snd = λp. p false

That is construct_pair f s returns a pair which is a function that, when applied to a boolean value b, applied b to f and s

Encoding LISP-style lists

carcdr 入手,The way we'll define a non-nil list is as a function that "stores" the head and tail of the list in its body. Its argument will be a selector function (head or tail).

<!-- type list = λs.s h t -->
car = λl.l (λh.λt.h) = λl.l true
cdr = λl.l (λh.λt.t) = λl.l false

is_empty = λl.l (λh.λt.false)
nil = λs.true

CONS = λh.λt.(λs.s h t)

Encoding Natural Numbers

可以用 list 来实现

ISZERO == ISEMPTY
PRED == TAIL
SUCC is a function that adds one more element onto a given list, so: SUCC == λL.CONS x L

根据函数 apply 的次数来实现

n = λx.λy.x^n y

0	==	λx.λy.y
1	==	λx.λy.xy
2	==	λx.λy.x(xy)
3	==	λx.λy.x(x(xy))
etc.
ISZERO = λf.f(λx.FALSE)TRUE
n != 0 即 x 一旦 apply 就返回 falses,那么 let `x` be `λx.FALSE`
n == 0 即 y 直接返回就返回 true,那么 let `y` be `True`

那么需要接受一个数返回另一个数,即接受一个接受两个参数的函数返回一个接受两个参数的函数。区别在于第二个函数的第一个参数多 apply 一次,但是我们无法改变参数函数的 function body,不妨在 apply 到函数之前,先让 x apply y 一次。 SUCC == λa.(λx.λy.a x (xy))

module type ChurchNumber = sig
  (* in untyped lambda calculus, we can use a generic type instead of bool *)
  (* we use bool here because of is_zero *)
  type t = (bool -> bool) -> bool -> bool

  val zero : t

  val one : t

  val two : t

  val is_zero : t -> bool

  val add : t -> t -> t

  val mult : t -> t -> t
end

module ChurchNumber : ChurchNumber = struct
  type t = (bool -> bool) -> bool -> bool

  let zero f b = b

  let one f b = f (f b)

  let two f b = f (f (f b))

  let is_zero n = n (fun _ -> false) true

  let add x y f b = x f (y f b)

  let mult x y f b = x (y f) b
end

zz = pair 0 0
ss = λp. pair (snd p) (succ (snd p))
pred = λn. fst (n ss zz)

The key part of this definition is ss (a, b) = (b, b + 1)。so we have ss^n (0, 0) = (n - 1, n),所以可以有 pred n = fst $ n ss (0, 0)

substract: TODO... equal: TODO...