lambda演算中列表元素的总和和列表的长度

时间:2017-09-12 22:44:46

标签: functional-programming lambda-calculus

我试图在lambda演算中计算列表元素和列表长度的函数 列表示例:a := [1, 2, 3] = λcn.c 1 (c 2 (c 3 n))
sum a应返回6,len a应返回3.

我写了递归版本:

len = λl.if (empty l) 0 (plus 1 (len (tail l)))
sum = λl.if (empty l) 0 (plus (head l) (sum (tail l)))

其中if,empty,plus,tail是其他lamda函数。

然后我用定点组合器做了一些技巧:

len = λl.if (empty l) 0 (plus 1 (len (tail l))) 
len = λfl.if (empty l) 0 (plus 1 (f (tail l))) len
len = Y λfl.if (empty l) 0 (plus 1 (f (tail l)))

其中Y = λf.(λx.f(x x))(λx.f(x x))
总和也差不多。所以现在我有非递归版本。但是我不能在这里使用beta减少来获得beta正常形式 我想知道这些功能是否存在β正常形式以及它们的外观。

1 个答案:

答案 0 :(得分:4)

这些可以更容易实现,因为列表由其自己的迭代器编码:

a := [1, 2, 3] = λcn.c 1 (c 2 (c 3 n))

表示列表是两个参数的函数:一个用于cons个节点,另一个用于nil构造函数的末尾。

因此,您可以通过以下方式实施length

  • 忽略存储在cons节点中的值并返回+1
  • nil替换为0

转换为:

length := λl. l (λ_. plus 1) 0

将扩展为(在每一行,粗体表达式展开或缩小):

length a
(λl. l (λ_. plus 1) 0) al. l (λ_. plus 1) 0) (λcn.c 1 (c 2 (c 3 n)))cn. c 1 (c 2 (c 3 n))) (λ_. plus 1) 0
(λn. (λ_. plus 1) 1 ((λ_. plus 1) 2 ((λ_. plus 1) 3 0))) 0_. plus 1) 1 ((λ_. plus 1) 2 ((λ_. plus 1) 3 0))
(plus 1) ((λ_. plus 1) 2 ((λ_. plus 1) 3 0))
(plus 1) ((plus 1) ((λ_. plus 1) 3 0))
(plus 1) ((plus 1) ((plus 1) 0))
(plus 1) ((plus 1) 1)
(plus 1) 2
= 3

同样,您可以通过说:

来实施sum
  • 使用+合并cons中存储的值和评估尾部的结果
  • nil替换为0

转换为:

sum := λl. l plus 0

将扩展为

sum a
(λl. l plus 0) al. l plus 0) (λcn.c 1 (c 2 (c 3 n)))cn. c 1 (c 2 (c 3 n))) plus 0
(λn. plus 1 (plus 2 (plus 3 n))) 0
plus 1 (plus 2 (plus 3 0))
plus 1 (plus 2 3)
plus 1 5
= 6