示例:序对无穷流

讲解如何用交错的方式构造所有满足 i ≤ j 且 i + j 为素数的整数序对无穷流。

假设我们要产生一条无穷流,其中包含所有满足 i≤ji \le j 且 i+ji + j 为素数的整数序对 (i,j)(i, j)。如果 int-pairs 是所有整数的序对组成的流,那么我们要的流就是:

(stream-filter (lambda (pair)
                 (prime? (+ (car pair) (cadr pair))))
               int-pairs)

现在唯一要做的就是定义 int-pairs。怎么做呢?先假设我们有两条流 SS 和 TT,它们都等价于 integers。想象由 SS 和 TT 的元素组成的数组(也可以看成矩阵)中的序对:

序对矩阵

整数的序对流就是对角线以上的全部内容:

对角线以上的序对流

把一般的序对流记作 (pairs s t),它由三部分组成:序对 (S0,T0)(S_0, T_0)、第一行中其余的序对,以及剩下的序对。

序对流的分解

这个分解中的第三块(不在第一行的那些序对),(递归地)就是由 (stream-cdr s) 和 (stream-cdr t) 形成的序对。另外注意,第二块(第一行其余的序对)是:

(stream-map (lambda (x) (list (stream-car s) x))
            (stream-cdr t))

于是我们的序对流就是:

(define (pairs s t)
  (cons-stream (list (stream-car s) (stream-car t))
               (combine (stream-map (lambda (x) (list (stream-car s) x))
                                    (stream-cdr t))
                        (pairs (stream-cdr s) (stream-cdr t)))))

现在只需要用某种 combine 函数把两条流接起来。我们知道追加行不通——用 interleave 吧!我们的序对流变成:

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