带 Y 组合器的列表函数没有递归,为什么?

发布于 2024-12-18 01:14:27 字数 593 浏览 2 评论 0原文

注意:这是一种家庭作业,而不是一种家庭作业——最终目标是拥有一个函数,该函数生成一组数字的幂集,以数字列表的形式提供给该函数。我有该函数的递归版本,但我现在需要找到一些方法来替换我拥有的解决方案中的每个显式递归函数(appendmapm 等)等效的仅 lambda 表达式。

因此,我从较小的问题开始,希望将它们全部结合起来编写一个完整的函数。我已经设法使用纯 lambda (Y 组合器)想出一个非递归阶乘函数,但我现在尝试想出一个很好的函数,可以对列表中的每个数字进行平方 - 尝试在跳转之前解决较小的问题直到多重递归函数:

(define (sqrlist numlist)
  (((lambda (f)
   ((lambda (x) (x x))
    (lambda (g)
     (f (lambda (x) ((g g) x))))))
  (lambda (f)
   (lambda (x)
    (cons (sqr (first x)) (rest x))))) numlist))

上面的代码不会递归,尽管前面存在 Y 组合器 - 我显然在将正确的参数传递给其中的函数时遇到了一些问题 - 有什么想法吗?

Note: This is kind of homework, kind of not -- the end goal is to have a function that produces a powerset of a set of numbers supplied to the function as a list of numbers. I have a recursive version of the function but I now need to find some ways of replacing each explicitly recursive function in the solution I have (append, mapm etc.) with an equivalent lambda-only expression.

As such, I am starting with smaller problems and hope to combine them all to write a full function. I've managed to come up with a non-recursive factorial function using pure-lambda (Y combinator) but I am now trying to come up with a nice function that squares every number in a list -- trying to solve smaller problems before jumping up to a multiply-recursive function:

(define (sqrlist numlist)
  (((lambda (f)
   ((lambda (x) (x x))
    (lambda (g)
     (f (lambda (x) ((g g) x))))))
  (lambda (f)
   (lambda (x)
    (cons (sqr (first x)) (rest x))))) numlist))

The code above doesn't recurse, despite the presence of the Y combinator before it -- I'm obviously having some issues passing the proper parameters to the functions within -- any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

强辩 2024-12-25 01:14:27

如果您有工作流程,则转换为匿名流程相对简单且机械。给每个 lambda 一个额外的参数,即“它自己”,并重复该过程。所以

(define (add-list list) 
  (if (empty? list) 
      0 
      (+ (first list) (add-list (rest list)))))

变成

(λ(list) (if (empty? list) 0 (+ (first list) (add-list (rest list)))))

这当然是一个问题,因为 add-list 没有定义。因此,我们必须确保每次都能通过我们自己

(λ(self list) (if (empty? list) 0 (+ (first list) (self self (rest list)))))

但我们首先要到哪里去呢?好吧,我们复制并粘贴(并给它一个参数)

((λ(self list) (if (empty? list) 0 (+ (first list) (self self (rest list)))))
 (λ(self list) (if (empty? list) 0 (+ (first list) (self self (rest list)))))
 '(1 2 3 4))

将这种“复制和粘贴”抽象为 Y 组合器在 "The Why of Y" (PDF),您一定要查看一下。

但请记住第一步是“让它发挥作用”。 抽象定义之前执行此操作。

If you have a working procedure, converting to anonymous procedures is relatively straightforward and mechanical. Give each lambda an extra argument, which is "itself", and duplicate the procedure. So

(define (add-list list) 
  (if (empty? list) 
      0 
      (+ (first list) (add-list (rest list)))))

Becomes

(λ(list) (if (empty? list) 0 (+ (first list) (add-list (rest list)))))

This is of course a problem because add-list isn't defined. So we're going to have to ensure that we pass ourselves around every time.

(λ(self list) (if (empty? list) 0 (+ (first list) (self self (rest list)))))

But where do we get ourselves in the first place? Well, we copy and paste (and give it an argument)

((λ(self list) (if (empty? list) 0 (+ (first list) (self self (rest list)))))
 (λ(self list) (if (empty? list) 0 (+ (first list) (self self (rest list)))))
 '(1 2 3 4))

Abstracting this "copy and paste" to the Y combinator is developed excellently in "The Why of Y" (PDF) and you should definitely check it out.

But remember the first step was "get it working." Do this before you abstract away defines.

紫竹語嫣☆ 2024-12-25 01:14:27

这是一个可能的答案,我知道你已经解决了它,但有第二个意见可能会很有用:)

((lambda (X)
    ((lambda (proc)
       (proc proc))
     (lambda (proc)
       (X (lambda (arg)
            ((proc proc) arg))))))
  (lambda (sqrlist)
    (lambda (lst)
      (if (null? lst)
          '()
          (cons (* (car lst) (car lst))
                (sqrlist (cdr lst)))))))

它是“仅限 lambda”,因为它专门用匿名函数编写,它甚至不使用 定义。调用方法如下:

(((lambda (X)
     ((lambda (proc)
        (proc proc))
      (lambda (proc)
        (X (lambda (arg)
             ((proc proc) arg))))))
   (lambda (sqrlist)
     (lambda (lst)
       (if (null? lst)
           '()
           (cons (* (car lst) (car lst))
                 (sqrlist (cdr lst)))))))
 '(1 2 3 4 5))

Here's a possible answer, I know that you solved it already, but it could be useful to have a second opinion :)

((lambda (X)
    ((lambda (proc)
       (proc proc))
     (lambda (proc)
       (X (lambda (arg)
            ((proc proc) arg))))))
  (lambda (sqrlist)
    (lambda (lst)
      (if (null? lst)
          '()
          (cons (* (car lst) (car lst))
                (sqrlist (cdr lst)))))))

It's "lambda-only" since it's written exclusively in terms of anonymous functions, it doesn't even use define. Here's how to call it:

(((lambda (X)
     ((lambda (proc)
        (proc proc))
      (lambda (proc)
        (X (lambda (arg)
             ((proc proc) arg))))))
   (lambda (sqrlist)
     (lambda (lst)
       (if (null? lst)
           '()
           (cons (* (car lst) (car lst))
                 (sqrlist (cdr lst)))))))
 '(1 2 3 4 5))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文