2

我试图了解如何在方案中将函数作为参数传递,但我在理解教程时遇到了很多麻烦。这是我正在尝试做的事情:

(define (addone n)
(+ n 1))
(define (for-n start stop fn)
(if (< start stop)
    (list)
    (cons (fn start) (for-n (+ start 1) stop fn))))

基本上我只想要一个函数,它返回 fn 的值,用于列表中的 start、start+1、... start+stop。

因此 (for-n 1 5 (addone 0)) 的预期输出将是 (1 2 3 4 5)。我认为我在这里真的错过了一些非常基本的概念,因为我似乎甚至没有正确调用解释器中的函数,而且我没有掌握如何告诉方案将 fn 解释为一个函数而不仅仅是一个常规参数.

我想通了(尽管通过纯粹的试验和错误),我不确定我做了什么,但至少它有效!

 (define (function x)
    x)
(define (for-n start stop fn)
  (if (> start stop)
    (list)
    (cons (fn start) (for-n (+ start 1) stop fn)))))
4

2 回答 2

1

一些反馈,让您知道您的第一个版本有什么问题:

  • 建立列表的递归的基本情况通常通常返回'()而不是(list)
  • 正如您已经发现的那样,基本情况的条件是错误的:递归结束的时间(> start stop)而不是(< start stop)最初声明的时间
  • 没有必要定义一个addone过程,至少在一些 Scheme 解释器中已经存在一个叫做add1
  • 最后,当调用接收另一个过程的过程时,只需传递函数,无需先应用它 - 这将返回一个而不是预期的函数。我的意思是,这是错误的:(for-n 1 5 (addone 0))这是正确的:(for-n 1 5 addone)。当您编写(addone 0)函数并返回值1时,您打算传递的是addone过程本身。

有了上述所有建议,正确的程序应该是这样的:

(define (for-n start stop fn)
  (if (> start stop)
      '()
      (cons (fn start) (for-n (add1 start) stop fn))))

像这样称呼它:

(for-n 1 5 add1)
> '(2 3 4 5 6)
于 2012-10-13T22:19:31.430 回答
1

函数调用(addone 0)等于 value 1。如果您想传递函数addone本身(而不是1),则根本不要将其包裹在括号中。(for-n 1 5 addone)addone函数传递给for-n. 如果你用括号括起来,Scheme 将调用addone并传递结果。

于 2012-10-13T21:20:47.283 回答