最近使用plt Scheme实现SICP上的一个关于stream的例子,就是动态的产生序列:即我们只产生当前需要的序列数,例如:一个序列从10000到1000000,求解其中第二个素数,当然我们可以简单的从头开始,一个一个验证,可如此与我们抽象观念相悖,因为它模块性不强,不易扩展。
但如果我们直接产生上述序列,然后模块化的一个个验证,将浪费很多资源。
我们如此设计过程:
建立流(一种特殊的表,可以延时)
(define the-empty-stream '())
(define (cons-stream a b)
(cons a (delay b)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
delay过程可以先简单的实现为一个过程,成为一个promise
force可以打开这种promise
之后建立一个流:
(1 . #<promise>)
只产生第一个数据,第二个为一个promise,当需要第二个数时,force产生过程,生成第二个数,如此产生下去.....
;Mar,3,2010 so long no working,just can not focus my attention on it
;now you know,you have to do better,'cause everyone's doing sth
;3.5 Stream
(define (square n)
(* n n))
(define (filter pred sequence)
(cond ((null? sequence) '())
((pred (car sequence))
(cons (car sequence)
(filter pred
(cdr sequence))))
(else (filter pred (cdr sequence)))))
(define (prime? n)
(= n (small-divisor n)))
(define (small-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? n test-divisor) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(define (divides? n test-divisor)
(= (remainder n test-divisor) 0))
(prime? 1211)
(define (enumerate-interval low high)
(if (> low high)
'()
(cons low
(enumerate-interval (+ low 1) high))))
(enumerate-interval 1 12)
(car (cdr (filter prime?
(enumerate-interval 10000 100000))))
;上述是简单序列
;下述为特殊序列--流
(define the-empty-stream '())
(define (cons-stream a b)
(cons a (delay b)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (stream-map proc s)
(if (null? s)
the-empty-stream
(cons-stream (proc (stream-car s))
(stream-map proc (stream-cdr s)))))
(define (stream-for-each proc s)
(if (null? s)
'done
(begin (proc (stream-car s))
(stream-for-each proc (stream-cdr s)))))
(define (display-stream s)
(stream-for-each display-line s))
(define (display-line x)
(newline)
(display x))
(define (stream-filter pred s)
(cond ((null? s) the-empty-stream)
((pred (stream-car s))
(cons-stream (stream-car s)
(stream-filter pred (stream-cdr s))))
(else (stream-filter pred (stream-cdr s)))))
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream low
(stream-enumerate-interval (+ low 1) high))))
;关键实现
;delay and force-my
(define (delay x)
(lambda () x))
(define (force-my delayed-object)
(delayed-object))
(stream-enumerate-interval 1 12)
(cdr (stream-enumerate-interval 1 12))
(stream-cdr (stream-enumerate-interval 1 12))
(display-stream (stream-enumerate-interval 1 4))
(stream-car
(stream-cdr
(stream-filter prime?
(stream-enumerate-interval 10000 100000))))