3.67

 
;3.67
(define (pairs s t)
  (interleave
   (stream-map (lambda (x) (list (stream-car s) x)
                 t))
   (pairs (stream-cdr s) t)))


这里给出 一个 高人的解释 豁然开朗

Exercise 3.68. 答案

  • 分析:
    1. (define (pairs s t)
    2.   (interleave
    3.    (stream-map (lambda (x) (list (stream-car s) x))
    4.                t)
    5.    (pairs (stream-cdr s) (stream-cdr t))))
    复制代码


    问题出在对 interleave 的调用和 pairs 的自引用上。

    • interleave 是函数,所以先求值其参数,
    • stream-map 调用 cons-stream,它是个宏,不对参数求值,所以能终止。
    • 但 interleave 对第二个参数的求值 (pairs (stream-cdr s) (stream-cdr t)) 不会终止。它会不断调用 pairs,直到耗尽所有空间。


    对比一下原来的 pairs

    1. (define (pairs s t)
    2.   (cons-stream
    3.    (list (stream-car s) (stream-car t))
    4.    (interleave
    5.     (stream-map (lambda (x) (list (stream-car s) x))
    6.                (stream-cdr t))
    7.     (pairs (stream-cdr s) (stream-cdr t)))))
    复制代码


    这里也存在 interleave 和 pairs,但此时是包含在一个 cons-stream 里的。cons-stream 是宏,不会对参数穷追猛打。
  • 其实 Louis Reasoner 的方案比我们最初的方案更为自然。但由于 scheme 的函数调用是严格的,所以他的方案行不通。
    如果我们更进一步,把 scheme 的函数调用也修改为惰性的,那么 Louis Reasoner 的方案就可行了。

    用 lazy scheme 来试一下:

    1. #lang lazy

    2. (define (interleave s1 s2)
    3.   (cons (car s1)
    4.         (interleave s2 (cdr s1))))

    5. (define (pairs s t)
    6.   (interleave
    7.    (map (lambda (x) (list (car s) x))
    8.         t)

    9.    (pairs (cdr s) (cdr t))))

    10. (define (integers-starting-from n)
    11.   (cons n (integers-starting-from (+ n 1))))

    12. (define integers (integers-starting-from 1))
    复制代码


    这里要使用 mzsheme 解释器。

    1. > (define x (pairs integers integers))
    2. > (display (take 10 x))
    3. ((1 1) (2 2) (1 2) (3 3) (1 3) (2 3) (1 4) (4 4) (1 5) (2 4))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值