【问题标题】:Creating a list of ordered pairs in lambda calculus using recursion使用递归在 lambda 演算中创建有序对列表
【发布时间】:2018-04-28 03:35:52
【问题描述】:

我的输入是两个列表,即 l = [x1, x2, x3,...,xn] 和 k = [y1, y2, y3,...,yn]

我想要一个 y = [(x1,y1),(x2,y2),(x3,y3)...(xn,yn)] 输出。

如何将递归应用于我的代码?我可以用 f = \l k. (cons (pair (head l) (head k)) empty) 但我不明白如何使用递归来创建其他项目。

函数“head”返回列表的第一项,函数“tail”返回没有第一项的列表。

【问题讨论】:

  • 在 lambda 演算中?您正在使用哪种列表表示形式?你如何表示对?

标签: recursion lambda lambda-calculus calculus


【解决方案1】:

当然,这完全取决于您如何在 Lambda 演算中实现元组、列表等。但是假设标准功能 cons 列表,并且两个列表的长度相同,并且您已经定义了以下帮助程序,其中一些您已经引用了:

cons    -- construct a list from a node and another list
empty   -- the empty list
head    -- retrieve the first node value of a list
tail    -- retrieve all but the first node of a list
pair    -- pair values into a tuple
isEmpty -- return `true` if a list is `empty`, `false` otherwise
true    -- return the first argument
false   -- return the second argument

然后我们可以递归压缩列表如下:

ZIP = λlk. isEmpty l -- "if the list is empty…"
           empty     -- "return an empty result. Else…"
           (cons     -- "return a new list, containing…"
               (pair (head l) (head k))  -- "the zipped heads, and…"
               (ZIP  (tail l) (tail k))) -- "everything else zipped."

问题当然是原始的 lambda 演算没有 递归。您不能在其自己的定义中引用函数名称。答案是使用fixed-point combinator, e.g. the famous Y combinator

ZIP = Y (λzlk. isEmpty l empty (cons (pair (head l) (head k)) (z (tail l) (tail k)))

Y的定义是:

Y = λf.(λx.f(x x))(λx.f(x x))

解开这个工作的精确度是一个令人印象深刻的心理体操,它不是这个问题的范围,但是使用它非常简单。一般来说,如果你有一个想要的(但在原始 LC 中是非法的)递归定义,如下所示:

R = λ ??? . ??? R ???

你可以把它写成完全合法的、非递归的定义:

R = Y (λr ??? . ??? r ???)

换句话说,为你的函数添加一个新参数,代表你的递归函数,并使用Y 为你连接一切。 Y 可以从零开始发明递归,这很了不起,也是它如此出名的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    相关资源
    最近更新 更多