方案中的简单高阶函数

时间:2012-10-13 18:53:59

标签: function scheme

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

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

2 个答案:

答案 0 :(得分:1)

函数调用(addone 0)等于值1。如果要传递函数addone本身(而不是1),请不要将它包装在括号中。 (for-n 1 5 addone)addone函数传递给for-n。如果用括号括起来,Scheme会调用addone并传递结果。

答案 1 :(得分: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)