sicp-ex-3.50



<< Previous exercise (3.49) | Index | Next exercise (3.51) >>


meteorgan



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

argstreams is a list of list, not a stream, we should not use stream-xxx procs on it.

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

That implementation assumes that the streams are the same length (perhaps infinite). In order to cope with streams of different lengths I have this:

 (define (filter predicate list) 
   (cond ((null? list) 
          '()) 
         ((predicate (car list)) 
          (cons (car list) (filter predicate (cdr list)))) 
         (else 
          (filter predicate (cdr list))))) 
 (define (stream-map proc . argstreams) 
   (let ((non-null-args (filter (lambda (s) (not (stream-null? s))) argstreams))) 
     (if (null? non-null-args) 
       the-empty-stream 
       (cons-stream 
        (apply proc (map stream-car non-null-args)) 
        (apply stream-map 
               (cons proc (map stream-cdr non-null-args))))))) 

A bit cleaner:

  
 (define (any? pred lst)  
   (cond ((null? lst) #f)   
         ((pred (car lst)) #t) 
         (else (any? pred (cdr lst))))) 
  
 (define (stream-map proc . streams)  
   (if (any? stream-null? streams)  
       empty-stream 
       (stream-cons 
         (apply proc (map stream-car streams)) 
         (apply stream-map  
                proc ; We don't need to cons proc and the result of map. 
                (map stream-cdr streams))))) 

to Beckett, i think argstream is a list of stream not list of list. so it is correct to map it by stream-xxx. (map each stream by stream-xxx)