source: project/release/5/srfi-41/trunk/streams-utils.incl.scm @ 39989

Last change on this file since 39989 was 39989, checked in by Kon Lovett, 5 months ago

per dieggsy irc "... (streams derived) as the srfi suggests"

File size: 10.0 KB
Line 
1;;;; streams-utils.incl.scm
2;;;; Kon Lovett, Feb '19
3;;;; Kon Lovett, Apr '09
4
5; Copyright (C) 2007 by Philip L. Bewig of Saint Louis, Missouri, USA.  All rights
6; reserved.  Permission is hereby granted, free of charge, to any person obtaining a copy of
7; this software and associated documentation files (the "Software"), to deal in the Software
8; without restriction, including without limitation the rights to use, copy, modify, merge,
9; publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to
10; whom the Software is furnished to do so, subject to the following conditions: The above
11; copyright notice and this permission notice shall be included in all copies or substantial
12; portions of the Software.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
14; FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16; CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
17; THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
19;;;
20
21(define-inline (%check-streams loc strms #!optional argnam)
22  (when (null? strms) (error loc "no stream arguments" strms))
23  (for-each (cut check-stream loc <> argnam) strms)
24  strms )
25
26;(append xs args) = (reverse (append (reverse args) (reverse xs)))
27(define (right-section fn . args) (lambda xs (apply fn (append xs args))))
28
29;;;
30
31(define-stream (stream-intersperse yy x)
32  (stream-match (check-stream 'stream-intersperse yy 'stream)
33    (()
34      (stream (stream x)) )
35    ((y . ys)
36      (stream-append
37        (stream (stream-cons x yy))
38        (stream-map (lambda (z) (stream-cons y z)) (stream-intersperse ys x))) ) ) )
39
40(define-stream (stream-permutations xs)
41  (if (stream-null? (check-stream 'stream-permutations xs 'stream))
42    (stream (stream))
43    (stream-concat
44      (stream-map
45        (right-section stream-intersperse (stream-car xs))
46        (stream-permutations (stream-cdr xs)))) ) )
47
48(define-stream (file->stream filename #!optional (reader read-char))
49  (check-procedure 'file->streams reader 'reader)
50  (let ((port (open-input-file (check-string 'file->streams filename 'filename))))
51    (stream-let loop ((item (reader port)))
52      (if (eof-object? item)
53        (begin (close-input-port port) stream-null)
54        (stream-cons item (loop (reader port))) ) ) ) )
55
56(define (stream-split count strm)
57  (check-stream 'stream-split strm 'stream)
58  (check-natural-integer 'stream-split count 'count)
59  (values (stream-take count strm) (stream-drop count strm)))
60
61(define-stream (stream-unique eql? strm)
62  (check-procedure 'stream-unique eql? 'equivalence)
63  (stream-let loop ((strm (check-stream 'stream-unique strm 'stream)))
64    (if (stream-null? strm)
65      stream-null
66      (stream-cons
67        (stream-car strm)
68        (loop (stream-drop-while (lambda (x) (eql? (stream-car strm) x)) strm))) ) ) )
69
70(define (stream-fold-one func strm)
71  (check-stream 'stream-fold-one strm 'stream)
72  (stream-fold
73    (check-procedure 'stream-fold-one func 'function)
74    (stream-car strm)
75    (stream-cdr strm)) )
76
77(define-stream (stream-member eql? item strm)
78  (check-procedure 'stream-member eql? 'equivalence)
79  (stream-let loop ((strm (check-stream 'stream-member strm 'stream)))
80    (cond
81      ((stream-null? strm)
82        #f)
83      ((eql? item (stream-car strm))
84        strm)
85      (else
86        (loop (stream-cdr strm)) ) ) ) )
87
88(define-stream (stream-merge lt? . strms)
89  ;
90  (define-stream (stream-merge$ xx yy)
91    (stream-match xx
92      (()
93        yy )
94      ((x . xs)
95        (stream-match yy
96          (() xx )
97          ((y . ys)
98            (if (lt? y x) (stream-cons y (stream-merge$ xx ys))
99              (stream-cons x (stream-merge$ xs yy))))) ) ) )
100  ;
101  (check-procedure 'stream-merge lt? 'less-than)
102  (stream-let loop ((strms (%check-streams 'stream-merge strms 'stream)))
103    (cond
104      ((null? strms)
105        stream-null )
106      ((null? (cdr strms))
107        (car strms) )
108      (else
109        (stream-merge$ (car strms) (apply stream-merge lt? (cdr strms))) ) ) ) )
110
111(define (stream-partition pred? strm)
112  (check-procedure 'stream-partition pred? 'predicate)
113  (stream-unfolds
114    (lambda (s)
115      (if (stream-null? s) (values s '() '())
116        (let ((a (stream-car s))
117              (d (stream-cdr s)))
118          (if (pred? a)
119            (values d (list a) #f)
120            (values d #f (list a)) ) ) ) )
121    (check-stream 'stream-partition strm 'stream)) )
122
123(define-stream (stream-finds eql? item strm)
124  (check-procedure 'stream-finds eql? 'equivalence)
125  (stream-of
126    (car x)
127    (x in (stream-zip (stream-from 0) (check-stream 'stream-finds strm 'stream)))
128    (eql? item (cadr x))) )
129
130(define (stream-find eql? item strm)
131  (check-stream 'stream-find strm 'stream)
132  (check-procedure 'stream-find eql? 'equivalence)
133  (stream-car (stream-append (stream-finds eql? item strm) (stream #f))) )
134
135(define-stream (stream-remove pred? strm)
136  (check-procedure 'stream-remove pred? 'predicate)
137  (stream-filter (complement pred?) (check-stream 'stream-remove strm 'stream)) )
138
139(define (stream-every pred? strm)
140  (check-procedure 'stream-every pred? 'predicate)
141  (let loop ((strm (check-stream 'stream-every strm 'stream)))
142    (cond
143      ((stream-null? strm)
144        #t )
145      ((not (pred? (stream-car strm)))
146        #f )
147      (else
148        (loop (stream-cdr strm)) ) ) ) )
149
150(define (stream-any pred? strm)
151  (check-procedure 'stream-any pred? 'predicate)
152  (let loop ((strm (check-stream 'stream-any strm 'stream)))
153    (cond
154      ((stream-null? strm)
155        #f )
156      ((pred? (stream-car strm))
157        #t )
158      (else
159        (loop (stream-cdr strm)) ) ) ) )
160
161(define (stream-and strm)
162  (let loop ((strm (check-stream 'stream-and strm 'stream)))
163    (cond
164      ((stream-null? strm)
165        #t )
166      ((not (stream-car strm))
167        #f )
168      (else
169        (loop (stream-cdr strm)) ) ) ) )
170
171(define (stream-or strm)
172  (check-stream 'stream-or strm 'stream)
173  (let loop ((strm strm))
174    (cond
175      ((stream-null? strm)
176        #f )
177      ((stream-car strm)
178        #t )
179      (else
180        (loop (stream-cdr strm)) ) ) ) )
181
182(define (stream-fold-right func base strm)
183  (check-procedure 'stream-fold-right func 'function)
184  (let loop ((strm (check-stream 'stream-fold-right strm 'stream)))
185    (if (stream-null? strm)
186      base
187      (func (stream-car strm) (loop (stream-cdr strm))) ) ) )
188
189(define (stream-fold-right-one func strm)
190  (check-procedure 'stream-fold-right-one func 'function)
191  (let loop ((strm (check-stream 'stream-fold-right-one strm 'stream)))
192    (stream-match strm
193      ((x) x )
194      ((x . xs) (func x (loop xs)) ) ) ) )
195
196(define (stream-assoc key dict #!optional (eql? equal?))
197  (check-procedure 'stream-assoc eql? 'equivalence)
198  (let loop ((dict (check-stream 'stream-assoc dict 'stream)))
199    (cond
200      ((stream-null? dict)
201        #f )
202      ((eql? key (car (stream-car dict)))
203        (stream-car dict) )
204      (else
205        (loop (stream-cdr dict)) ) ) ) )
206
207; May never return
208(define (stream-equal? eql? xs ys)
209  (let loop ((xs (check-stream 'stream-equal? xs 'stream1))
210             (ys (check-stream 'stream-equal? ys 'stream2)))
211    (cond
212      ((and (stream-null? xs) (stream-null? ys))
213        #t )
214      ((or (stream-null? xs) (stream-null? ys))
215        #f )
216      ((not (eql? (stream-car xs) (stream-car ys)))
217        #f )
218      (else
219        (loop (stream-cdr xs) (stream-cdr ys)) ) ) ) )
220
221(define-stream (stream-quick-sort lt? strm)
222  (check-procedure 'stream-quick-sort lt? 'less-than)
223  (let loop ((strm (check-stream 'stream-quick-sort strm 'stream)))
224    (if (stream-null? strm)
225      stream-null
226      (let ((x (stream-car strm))
227            (xs (stream-cdr strm)))
228        (stream-append
229          (loop (stream-filter (lambda (u) (lt? u x)) xs))
230          (stream x)
231          (loop (stream-filter (lambda (u) (not (lt? u x))) xs))) ) ) ) )
232
233(define-stream (stream-insertion-sort lt? strm)
234  ;
235  (define-stream (insert$ strm x)
236    (stream-match strm
237      (()
238        (stream x) )
239      ((y . ys)
240        (if (lt? y x) (stream-cons y (insert$ ys x))
241          (stream-cons x strm) ) ) ) )
242  ;
243  (check-procedure 'stream-insertion-sort lt? 'less-than)
244  (stream-fold insert$ stream-null (check-stream 'stream-insertion-sort strm 'stream)) )
245
246(define-stream (stream-merge-sort lt? strm)
247  (check-procedure 'stream-merge-sort lt? 'less-than)
248  (let loop ((strm (check-stream 'stream-merge-sort strm 'stream)))
249    (let ((n (quotient (stream-length strm) 2)))
250      (if (zero? n)
251        strm
252        (stream-merge lt? (loop (stream-take n strm)) (loop (stream-drop n strm))) ) ) ) )
253
254(define (stream-maximum lt? strm)
255  (check-procedure 'stream-maximum lt? 'less-than)
256  (stream-fold-one
257    (lambda (x y) (if (lt? x y) y x))
258    (check-stream 'stream-maximum strm 'stream)) )
259
260(define (stream-minimum lt? strm)
261  (check-procedure 'stream-minimum lt? 'less-than)
262  (stream-fold-one
263    (lambda (x y) (if (lt? x y) x y))
264    (check-stream 'stream-minimum strm 'stream)) )
265
266;; Lazy binary-tree "same fringe"
267
268(define (binary-tree-same-fringe? tree1 tree2 #!optional (eql? equal?))
269  ;
270  (define-stream (flatten tree)
271    (cond
272      ((null? tree)
273        stream-null )
274      ((pair? (car tree) )
275        (stream-append (flatten (car tree)) (flatten (cdr tree))))
276      (else
277        (stream-cons (car tree) (flatten (cdr tree))) ) ) )
278  ;
279  (let loop ((t1 (flatten (check-list 'same-fringe? tree1 'tree1)))
280             (t2 (flatten (check-list 'same-fringe? tree2 'tree2))))
281    (cond
282      ((and (stream-null? t1) (stream-null? t2))
283        #t )
284      ((or  (stream-null? t1) (stream-null? t2))
285        #f )
286      ((not (eql? (stream-car t1) (stream-car t2)))
287        #f )
288      (else
289        (loop (stream-cdr t1) (stream-cdr t2)) ) ) ) )
Note: See TracBrowser for help on using the repository browser.