【问题标题】:How to generate a list of lambdas in scheme?如何在方案中生成 lambda 列表?
【发布时间】:2018-11-15 16:48:13
【问题描述】:

我正在尝试创建一个过程,该过程采用 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(IE原始参数是一个返回20的过程,generate-list-of -numbers 列出(19 18 17... 3 2)

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

【问题讨论】:

  • 仔细研究你的递归调用。
  • 我在尝试使用它时遇到错误。递归调用的名称不正确,generate-list-of-numbers 应该是 generate-list-of-numbers-lambdas。我猜您没有收到错误,因为您还有一个使用该名称返回数字而不是 lambdas 的过程。
  • 如果你改正了那个错字就可以了。
  • 这个问题令人困惑。如果您真的想创建一个采用“lambda 列表”的过程,为什么它的参数是一个被调用以获得其返回值的函数?当我们说“一个函数需要”时,它指的是进入的参数值。
  • "...并使用这些 lambdas 的返回值"。以什么方式?计算什么返回值或产生什么输出?

标签: scheme lisp


【解决方案1】:

如果您重复使用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。最后,我们将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 结束是另一个晦涩的选择和危险信号。如果您能提供更广泛的目标,我或许可以更新答案并提供更多帮助。

【讨论】:

    猜你喜欢
    • 2010-12-25
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    相关资源
    最近更新 更多