如何在Scheme中生成Lambda列表?

时间:2018-11-15 16:48:13

标签: scheme lisp

我正在尝试制作一个过程,该过程需要一个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的过程, -list-of-numbers组成一个列表(19 18 17... 3 2)

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

1 个答案:

答案 0 :(得分:1)

如果您再次使用generate-list-of-numbers-lambdas而不是generate-list-of-numbers,则您的过程可以正常工作;您只是忘记了名称的-lambas部分。

还有两件事。您的程序在体内进行了3次(function)的呼叫。如果结果需要在多个地方使用,则应使用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。最后,我们将function重命名为n。这样一来,我们就可以纯粹根据数字进行思考,而不必将值包装在函数(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处结束列表是另一个晦涩的选择和危险信号。如果您可以提供更广泛的目标,我也许可以更新答案并提供其他帮助。