首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SICP 3.52延迟cdr

SICP 3.52延迟cdr
EN

Stack Overflow用户
提问于 2021-06-05 01:09:26
回答 1查看 68关注 0票数 1

练习3.52

代码语言:javascript
复制
(define sum 0)

(define (accum x)
  (set! sum (+ x sum))
  sum)

;1: (define seq (stream-map accum (stream-enumerate-interval 1 20)))
;2: (define y (stream-filter even? seq))
;3: (define z (stream-filter (lambda (x) (= (remainder x 5) 0))
;                           seq))

;4: (stream-ref y 7)
;5: (display-stream z)

步骤1: ;1: ==> (cons-stream 1 (stream-map proc (stream-cdr s)) (假设stream-cdr只有在强制执行该流的cdr时才进行评估)

sum现在是1

步骤2: 1不是偶数,因此(也是回忆录,所以没有再次添加),它调用了(stream-filter pred (stream-cdr stream))。这导致了对cdr的评估,从而实现了2的偶合,因此它应该调用:(cons-stream 2 (stream-cdr stream))

根据这个答案,应该是1+2 =3,但它是6

有人能帮上忙吗?为什么cdrcar在调用当前cdr之前就已经实现了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-05 14:21:18

使用tail

代码语言:javascript
复制
#lang r5rs

(define-syntax cons-stream
  (syntax-rules () 
    ((_ h t) (cons h (lambda () t)))))

(define (stream-cdr s)
  (if (and (not (pair? (cdr s)))
           (not (null? (cdr s))))
      (set-cdr! s ((cdr s))))
  (cdr s))

我们观察到:

代码语言:javascript
复制
> sum
0
> (define seq (stream-map accum (stream-enumerate-interval 1 20)))
> sum
1
> seq
(mcons 1 #<procedure:friedmans-tail.rkt:21:26>)
> (define y (stream-filter even? seq))
> sum
6
> seq
(mcons
 1
 (mcons
  3
  (mcons 6 #<procedure:friedmans-tail.rkt:21:26>)))
> y
(mcons 6 #<procedure:friedmans-tail.rkt:21:26>)
> 

为了构造流,stream-filter?需要到达它正在构建的流的第一个元素。流的头元素已经强制,计算出来了,所以它必须已经存在。

在从1到20的枚举区间的累积和列表中,第一个偶数为6:

代码语言:javascript
复制
1      = 1
1+2    = 3
1+2+3  = 6
...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67845454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档