程序作为论据 - 方案

时间:2016-10-26 04:25:19

标签: functional-programming scheme lisp

我正在使用以下一组方案定义。我的问题是关于“尾巴”功能。额外的括号组的作用是什么使得函数期望一个过程作为参数而不是一个列表,这是一组括号的情况?

(define (make-stream n f)
  (define (next m)
    (cons m (lambda () (next (f m)))))
  (next n))

(define head car)

(define (tail stream)
  ((cdr stream)))

(define (nth stream n)
  (if (= n 0) (head stream)
      (nth (tail stream) (- n 1))))

(define even (make-stream 0 (lambda (n) (+ n 2))))

如果格式不正确或者是其他不合适的问题,我很抱歉,我正在尝试学习如何使用本网站。

2 个答案:

答案 0 :(得分:1)

  

我的问题是关于"尾巴"功能。额外的括号组的作用是什么使得函数期望一个过程作为参数而不是一个列表,这是一组括号的情况?

这是您的程序

(define (make-stream n f)
  (define (next m)
    (cons m (lambda () (next (f m)))))
  (next n))

让我们先看一下carcdr会返回的内容

(car (make-stream 0 f) ; => 0
(cdr (make-stream 0 f) ; => (lambda () (next (f m)))

car返回的这个nullary(零参数)过程称为Thunk。它通常用于延迟计算的评估。在这种情况下,只要make-stream提供了两个参数,它就会阻止make-stream无限递归。

为了获得下一个值,我们所要做的就是应用thunk。注意这次额外的parens

((cdr (make-stream 0 f))) ;=> (next (f m))

这就是为什么你看到......

(define (tail stream) ((cdr stream)))

...将返回下一个cons,而不是......

(define (tail stream) (cdr stream))

...会返回包含下一个cons

的thunk

答案 1 :(得分:0)

在scheme中,表达式使用s-expression的第一个参数作为使用以下参数进行求值的方法。

例如:

(+ 1 2)

+应用于1和2。

如果我们稍微复杂一点,我们可以这样做。

(if (> x y) + -)

此表达式将返回+符号或-。我们可以进一步改变这个表达式......用这个:

((if (> x y) + -) 1 2)

此处if表达式将返回稍后将应用1和2的+-函数。

现在回到你的方法!

(define (tail stream)
  ((cdr stream)))

如您所见,您有双括号。这意味着它将应用cdr stream中的函数。就这么简单。

如果我们查看你的构造函数的流,我们可以看到你的构造函数实际上返回一个带有lambda函数的对作为第二个成员。

make-stream的第二个参数是一个被调用以生成下一个数字的函数。方法f不必与每个next调用一起传递,因为它在范围内可用。