Y Combinator的非递归列表功能

时间:2011-11-24 17:05:28

标签: lambda scheme racket y-combinator anonymous-recursion

注意:这是一种功课,有点不是 - 最终目标是拥有一个功能,可以将一组数字的powerset作为数字列表提供给函数。我是函数的递归版本,但我现在需要找到一些方法来替换我拥有的解决方案中的每个隐式递归函数(append,mapm等)和等效的lambda-only表达式。因此,我从较小的问题开始,并希望将它们全部组合起来编写一个完整的函数。我已经设法使用纯lambda(y-comb)提出了一个非递归因子函数,但我现在正试图想出一个很好的函数来对列表中的每个数字进行平方 - 试图在跳转之前解决较小的问题直到乘法递归函数。

(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-combinator,但上面的代码并没有递归 - 我显然有一些问题将适当的参数传递给其中的函数 - 任何想法?

2 个答案:

答案 0 :(得分:4)

如果您有工作程序,转换为匿名程序相对简单且机械。给每个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-combinator是在“The Why of Y”中得到了很好的发展,你一定要查看它。

但请记住,第一步是“让它运转起来”。在摘除define之前执行此操作。

答案 1 :(得分:0)

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

((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-only”,因为它是根据匿名函数编写的,它甚至不使用define。以下是如何调用它:

(((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))