SICP Exercise 3.52 流延迟求值sum计算结果不符原因问询
问题原因解析
核心问题出在你对seq流存储内容的理解有误,以及对stream-filter执行逻辑的推演漏了步骤:
首先明确两个基础前提:
- SICP 中
cons-stream的语义是(cons <第一个元素> (delay <后续流>)),只有第一个元素会在构造时立刻求值,后续流的求值会延迟到显式force seq是stream-map accum作用在120整数流上的结果,存储的不是原始的120整数,而是accum函数的返回值,也就是累加前缀和
我们完整复现执行到定义y时的所有步骤:
- 初始
sum = 0 - 执行
(define seq ...):- 首先构造整数流的第一个元素1,调用
(accum 1),sum变成0+1=1,seq的第一个元素为1,后续流延迟求值,这步你的推演是对的。
- 首先构造整数流的第一个元素1,调用
- 执行
(define y (stream-filter even? seq)):stream-filter第一步会先取当前流的第一个元素判断:第一个元素是1,不满足偶数条件,进入else分支,需要处理seq的后续流。- 为了拿到后续流,必须force
seq的延迟部分:取整数流的下一个元素2,调用(accum 2),sum变成1+2=3,得到seq的第二个元素为3,后续流继续延迟。 stream-filter拿到新的流后,先判断第一个元素3:还是不满足偶数,继续进入else分支,处理当前流的后续部分。- 再次force延迟部分:取整数流的下一个元素3,调用
(accum 3),sum变成3+3=6,得到seq的第三个元素为6,后续流延迟。 stream-filter判断第一个元素6:满足偶数条件,停止遍历,返回以6为第一个元素的过滤后流。
这就是为什么定义完y后sum的值是6而不是3:你误以为seq的第二个元素是2,但实际上seq存储的是累加和,第二个元素是3(奇数,不满足过滤条件),必须再往下遍历到第三个元素得到6(偶数)才会停止,这时候sum已经累加到6了。
内容的提问来源于stack exchange,提问作者user10206517
相关产品推荐
相关产品推荐

