首页 > 解决方案 > 如何在方案中生成 lambda 列表?

问题描述

我正在尝试制作一个程序,它需要一个 lambda 列表,并使用这些 lambda 的返回值。为了创建和填充这个列表,我做了这个过程:

(define generate-list-of-numbers-lambdas 
  (lambda (function) 
    (if (= (function) 3)
        (list (lambda () 2))
        (cons (lambda () (- (function) 1)) 
              (generate-list-of-numbers (lambda () (- (function) 1)))))))

此过程将过程作为参数,并从参数过程的返回值生成一个数字列表,直到2(即原始参数是一个返回的过程20,generate-list-of-numbers 生成一个列表(19 18 17... 3 2)

此过程将过程作为参数(参数过程本身没有参数,并且只返回一个整数),但是,此generate-list-of-numbers-lambdas过程会生成一个列表,但只有第一个元素是 lambda。

标签: schemelisp

解决方案


如果您重复使用generate-list-of-numbers-lambdas而不是,您的过程就可以正常工作generate-list-of-numbers;你只是忘记了-lambas名字的一部分。

不过还有几件事。(function)您的程序在体内调用了 3 次。如果结果需要在多个地方使用,则应使用let绑定。

(define generate-list-of-numbers
  (lambda (function)
    (let ((x (function))) ;; bind `x` to `(function)`
      (if (= x 3) ;; use x
          (list (lambda () 2))
          (cons (lambda () (- x 1)) ;; use x
                (generate-list-of-numbers (lambda () (- x 1)))))))) ;; use x

接下来,我们看到(lambda () ...)到处都是代码。少量的数据抽象在这里大有帮助——

(define num
  (lambda (x)
    (lambda () x)))

(define generate-list-of-numbers
  (lambda (function)
    (let ((x (function)))
      (if (= x 3)
          (list (num 2)) ;; use num
          (cons (num (- x 1)) ;; use num
                (generate-list-of-numbers (num (- x 1)))))))) ;; use num

;; calling our procedure is nicer too
(generate-list-of-numbers (num 20))

我们又看到(num (- x 1))了两次。它应该是一个let绑定。

(define generate-list-of-numbers
  (lambda (function)
    (let ((x (function)))
      (if (= x 3)
          (list (num 2))
          (let ((next (num (- x 1)))) ;; bind `next`
            (cons next (generate-list-of-numbers next)))))) ;; use `next` twice

我们过去常常num将数字放入容器中。我们将val用来取出数字。

(define val
  (lambda (n)
    (n)))

(map val (generate-list-of-numbers (num 20)))
;; '(19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2)

回过头来,我们看到我们也可以val在我们的程序中使用。最后,我们重命名functionn. 这使我们可以纯粹根据我们的数字来思考,而忘记值是包装在一个函数 ( thunk ) 或其他一些数据容器中的。

(define generate-list-of-numbers
  (lambda (n) ;; `function` renamed to `n`
    (let ((x (val n))) ;; use `val` to read value of `n`
      (if (= x 3)
          (list (num 2))
          (let ((next (num (- x 1))))
            (cons next (generate-list-of-numbers next)))))))

(map val (generate-list-of-numbers (num 20)))
;; '(19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2)

综上所述,这是一个奇怪的程序。我只能猜测这是一个家庭作业或什么的。似乎您正在尝试实现一个惰性数字列表,但这并不完全正确。列表的开始n - 1和结束2是另一个晦涩的选择和危险信号。如果您可以提供更广泛的目标,我可能会更新答案并提供更多帮助。


推荐阅读