Commits

Anonymous committed e73d353

Implement lazy-map and lazy-filter; replace lazy-iota with lazy-numbers

Comments (0)

Files changed (2)

 (lazy-seq make-lazy-seq
  lazy-seq? lazy-seq-realized?
  lazy-null lazy-null?
+ lazy-seq->list list->lazy-seq
  lazy-head lazy-tail
- lazy-take lazy-drop lazy-iota
- lazy-seq->list list->lazy-seq)
+ lazy-take lazy-drop
+ lazy-map lazy-filter
+ lazy-numbers)
 
 (import chicken scheme)
+(use srfi-1)
 
 (define-record lazy-seq
   body value)
       seq
       (lazy-drop (- n 1) (lazy-tail seq))))
 
-(define (lazy-iota count #!optional (start 0) (step 1))
-  (if (zero? count)
+(define (lazy-numbers #!key (step 1) (start 0) count)
+  (if (and count (zero? count))
       lazy-null
       (lazy-seq
         (cons start
-              (lazy-iota (- count 1)
-                         (+ start step)
-                         step)))))
+              (lazy-numbers count: (and count (- count 1))
+                            start: (+ start step)
+                            step:  step)))))
+
+(define (lazy-map proc . seqs)
+  (if (any lazy-null? seqs)
+      lazy-null
+      (lazy-seq
+        (cons (apply proc (map lazy-head seqs))
+              (apply lazy-map proc (map lazy-tail seqs))))))
+
+(define (lazy-filter pred? seq)
+  (if (lazy-null? seq)
+      lazy-null
+      (lazy-seq
+        (let loop ((seq seq))
+          (cond ((lazy-null? seq)
+                 lazy-null)
+                ((pred? (lazy-head seq))
+                 (cons (lazy-head seq)
+                       (lazy-filter pred? (lazy-tail seq))))
+                (else (loop (lazy-tail seq))))))))
 
 )
             (set! calls (+ calls 1))
             (cons n (natural-numbers (+ n 1)))))))
 
-  (define first-three
-    (lazy-seq->list (lazy-take 3 (natural-numbers))))
+  (define numbers (natural-numbers))
 
-  (test first-three '(0 1 2))
+  (test '(0 1 2) (lazy-seq->list (lazy-take 3 numbers)))
+  (test '(0 1 2) (lazy-seq->list (lazy-take 3 numbers)))
   (test calls 3))
 
 (test-group "lazy-seq-realized?"
-  (define even-numbers (lazy-iota 10000000 0 2))
+  (define even-numbers (lazy-numbers step: 2))
   (test-assert (not (lazy-seq-realized? even-numbers)))
   (test 0 (lazy-head even-numbers))
   (test-assert (lazy-seq-realized? even-numbers))
   (test-assert (lazy-seq-realized? seq))
   (test '("foo" "bar") (lazy-seq->list seq))
   (test-assert (lazy-null? (lazy-tail (lazy-tail seq)))))
+
+
+(test-group "lazy-map"
+  (test '(10 12 14)
+        (lazy-seq->list
+         (lazy-take 3 (lazy-map +
+                                (lazy-numbers start: 7)
+                                (lazy-numbers start: 3))))))
+
+
+(test-group "lazy-filter"
+  (test '(2 8 14 20 26)
+        (lazy-seq->list
+         (lazy-take 5 (lazy-filter
+                       (lambda (x) (zero? (modulo x 2)))
+                       (lazy-numbers start: 2 step: 3))))))
+
+
+(test-exit)