source: project/release/4/srfi-41/trunk/streams-utils.scm @ 14610

Last change on this file since 14610 was 14610, checked in by Kon Lovett, 11 years ago

Renamed obj to item to escape define-inline "coloring" issue.

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