-
Notifications
You must be signed in to change notification settings - Fork 0
/
preprefix.txt
152 lines (135 loc) · 3.98 KB
/
preprefix.txt
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
;; Boolean literals
(define true (= 1 1))
(define false (= 1 0))
(define #t true)
(define #f false)
;; Streams
;; See mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html
(define (force u) (u))
(define stream-car car)
(define (stream-cdr s) (force (cdr s)))
(define stream-null? null?)
(define the-empty-stream '())
;; List stuff
;; (list 1 2 3) => (1 2 3)
(define list
(lambda l
l))
;; `length' - r6rs.pdf, page 48
(define (length list)
(define (iter acc list)
(cond
((null? list) acc)
((pair? list)
(iter (+ acc 1) (cdr list)))
(else acc)))
(iter 0 list))
;; `list-tail' - r6rs.pdf, page 48
(define (list-tail list k)
(if (>= (length list) k)
(begin
(define (iter p c)
(if (= c 0)
p
(iter (cdr p) (- c 1))))
(iter list k))
'()))
;; `append' - r6rs.pdf, page 48
;; FIXME: naive recursive implementation, not iterative, explodes in space
;; ]=> (append '(a b) 'c '(d e f) '(g h) 'i)
;; (a b c d e f g h i)
(define append
(begin
;; 2-argument implementation
(define (append2 a b)
(cond
((null? a) b)
((pair? a)
(cons (car a) (append2 (cdr a) b)))
(else
(cons a (append2 '() b)))))
;; do a right-fold of append2 on the args
(lambda args
(define (iter l)
(if (null? l)
'()
(append2 (car l) (iter (cdr l)))))
(iter args))))
;; `list-ref' - r6rs.pdf, page 48
(define (list-ref list k)
(if (>= (length list) (+ k 1))
(begin
(define (iter count list)
(if (= count k)
(car list)
(iter (+ count 1) (cdr list))))
(iter 0 list))
'()))
;; Misc. library routines...
;; `odd?' -- see r6rs.pdf, page 42
(define (odd? n)
(= (remainder n 2) 1))
;; `even?'
(define even?
(lambda (u) (not (odd? u))))
;; `fold-right' -- see r6rs-lib.pdf, pages 11-12
(define (fold-right combine nil . lr)
(begin
;; append the list args together
(define biglist (apply append lr))
;; define a one-list foldr
(define (foldr1 c n l)
(if (null? l)
n
(c (car l) (foldr1 c n (cdr l)))))
;; run the one-list foldr on the combined list
(foldr1 combine nil biglist)))
;; `filter' -- see r6rs-lib.pdf, page 11
;; hopefully more efficient than the old one !
(define (filter proc list)
(define (iter acc l)
(if (null? l)
acc
(if (proc (car l))
(iter (cons (car l) acc) (cdr l))
(iter acc (cdr l)))))
(reverse (iter '() list)))
;; `map' -- see r6rs.pdf, page 49
(define (map proc . lr)
;; first define a one-arg map for internal use
(define (map1 proc list)
(define (iter acc p l)
(if (null? l)
acc
(iter (cons (p (car l)) acc) p (cdr l))))
(reverse (iter '() proc list)))
;; check that all list-args have same length
(define list-lengths (map1 length lr))
(define len1 (car list-lengths))
(define same-length
(= 0
(length (filter
(lambda (n) (not (= n len1)))
list-lengths))))
;; if they do, carry on...
(if same-length
(begin
;; `result' holds the final result in reverse order
(define result '())
;; `iter' is a loop that applies `proc' to a list containing
;; member `n' of each arg-list, consing the result onto `result',
;; for 0 <= `n' < `len1', where `len1' is the length of each
;; argument-list
(define (iter n)
(if (not (= n len1))
(begin
(set! result
(cons
(apply proc
(map1 (lambda (u) (list-ref u n)) lr))
result))
(iter (+ n 1)))))
;; run the loop
(iter 0)
;; reverse `result' to get the final answer...
(reverse result))))