summaryrefslogtreecommitdiff
path: root/shared/sicp-stream.rkt
blob: e7a28d03da725e8cf930f989081c7c18b280c4a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#lang racket
(require racket/stream)
(provide
 stream-cons
 stream-car
 stream-cdr
 the-empty-stream
 stream-null?
 display-line
 show
 display-stream
 stream-ref
 stream-for-each
 stream-enumerate-interval
 stream-map
 stream-filter)

;; (define (delay b) (lambda () b))
;; (define (force f) (f))
;; (define (cons-stream a b) (cons a (delay b)))
;; (define (cons-stream a b) (stream-cons  a b))
;; streams in racket by default are not eager for the head of the cons
(define (stream-car stream) (stream-first stream))
(define (stream-cdr stream) (stream-rest stream))
(define the-empty-stream (stream))
(define (stream-null? stream) (stream-empty? stream))
(define (display-line x) (newline) (display x))
(define (show x) (display-line x) x)
(define (display-stream s) (stream-for-each display-line s))

(define (stream-ref s n)
    (if (= n 0)
        (stream-car s)
        (stream-ref (stream-cdr s) (- n 1))))

(define (stream-for-each proc s)
    (if (stream-null? s)
        'done
        (begin (proc (stream-car s))
               (stream-for-each proc (stream-cdr s)))))

(define (stream-enumerate-interval low high)
    (if (> low high)
        the-empty-stream
        (stream-cons
         low
         (stream-enumerate-interval (+ low 1) high))))

(define (stream-map proc . argstreams)
    (if (stream-null? (car argstreams))
        the-empty-stream
        (stream-cons
         (apply proc (map stream-car argstreams))
         (apply stream-map
                (cons proc (map stream-cdr argstreams))))))

(define (stream-filter pred s)
    (cond ((stream-null? s) the-empty-stream)
          ((pred (stream-car s)) (stream-cons  (stream-car s) (stream-filter pred (stream-cdr s))))
          (else (stream-filter pred (stream-cdr s)))))