Answers:
首先编码自然数和对,如jmad所述。
将整数为一对自然数,使得。然后,您可以将整数的常规运算定义为(对 -calculus 使用Haskell表示法):
neg = \k -> (snd k, fst k)
add = \k m -> (fst k + fst m, snd k + snd m)
sub = \k m -> add k (neg m)
mul = \k m -> (fst k * fst m + snd k * snd m, fst k * snd m + snd k * fst m)
就复数被编码为一对实数的意义而言,复数的情况相似。但是一个更复杂的问题是如何对实数进行编码。在这里,您必须做更多的工作:
对实数进行编码是一项繁重的工作,您不想在微积分中实际进行编码。但是,例如,请参见Marshall的子目录,以了解纯Haskell中实数的简单实现。原则上,这可以转换为纯λ微积分。etc/haskell
i:ℤ
,x:a
,f,u,s:a→a
,p:(a→a,a→a)
]如果编码ℤ作为(Sign,ℕ)
然后,给定一对功能(s,f)
如p
,术语λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
会产生任一f(…f(x)…)
或s(f(…f(x)…))
(如果结果是负的)。如果将encode编码为(ℕ,ℕ)
,则需要一个具有反函数的函数-给定一个对,(f,u)
并且x
该函数λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
将产生u(…u(f(…f(x)…))…)
,将把f
应用i
时间赋予x
。两者都在不同的上下文中工作(结果可以被“翻转” || f
是可逆的)。
fold . ctor
适用于任何构造函数,且该类型的fold
(r
)。(这就是为什么对于递归类型,数据将“自行递归”的原因。对于非递归类型,它更像是case
/模式匹配。)
Lambda演算可以编码大多数数据结构和基本类型。例如,您可以使用通常用于编码非负整数和布尔值的相同的Church编码,在lambda演算中对一对现有项进行编码:
FST = λ p 。p (λ X ý 。X )SND = λ p 。p (λ X ý 。ÿ )
那么是p = (a b 对 ),如果你想取回a和b,你可以做(fst p )和 (snd p )。
这意味着您可以轻松地用一对来代表正整数和负整数:左侧的符号和右侧的绝对值。该符号是一个布尔值,指定数字是否为正。右边是使用Church编码的自然数。
现在您有了相对整数。乘法很容易定义,您只需要在符号上应用函数,并在绝对值上对自然数应用乘法:
要定义加法,您必须比较两个自然数并在符号不同时使用减法,因此这不是λ项,但是如果您确实想满足以下条件,可以对其进行调整:
但是减法真的很容易定义:
子ℤ = λ一个b。添加ℤ(一)(减去ℤ b)
一旦有了正整数和负整数,就可以非常容易地定义复数整数:它只是一对两个整数,代表a + b i。然后加法是逐点的,乘法是照常进行的,但是我不会写,应该很容易: