6

我正在研究 scip 的流部分,并被困在如何定义流上。

以下是我的代码:

(define (memo-func function)
  (let ((already-run? false)
        (result false))
    (lambda ()
      (if (not already-run?)
          (begin (set! result (function))
                 (set! already-run? true)
                 result)
          result))))


(define (delay exp)
  (memo-func (lambda () exp)))

(define (force function)
  (function))

(define the-empty-stream '())
(define (stream-null? stream) (null? stream))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))

(define (cons-stream a b) (cons a (memo-func (lambda () b))))

如果我按照书中描述的方式定义整数:

(define (integers-starting-from n)
   (cons-stream n (integers-starting-from (+ n 1))))
(define integers (integers-starting-from 1))

我收到一条消息:正在中止!:超出最大递归深度。

我猜延迟功能不起作用,但我不知道如何修复它。我在我的 Mac 上运行 MIT 方案。

更新 1

所以现在使用 cons-stream 作为宏,可以定义整数。

但后来我又遇到了另一个错误。

(define (stream-take n s)
  (cond ((or (stream-null? s)
             (= n 0)) the-empty-stream)
        (else (cons-stream (stream-car s)
                           (stream-take (- n 1) (stream-cdr s))))))

(stream-take 10 integers)
;ERROR - Variable reference to a syntactic keyword: cons-stream

更新 2

请忽略上面的更新1

4

2 回答 2

7

cons-stream需要是一个宏才能使您的示例代码正常工作。否则,调用cons-stream将急切地评估其所有参数。

试试这个(未测试):

(define-syntax cons-stream
  (syntax-rules ()
    ((cons-stream a b)
     (cons a (memo-func (lambda () b))))))

PSdelay由于类似的原因,您也需要成为宏。然后在你修复之后delay,你就可以直接cons-stream使用了delay

于 2013-02-01T06:36:44.010 回答
1

您不能将延迟定义为一个函数,因为在调用它之前,Scheme 会评估它的参数——这正是您想要推迟的。SICP明确表示延迟应该是一种特殊形式。

于 2014-03-14T08:54:51.767 回答