<< Previous exercise (2.35) | Index | Next exercise (2.37) >>



Given a sequence of sequences, applies accumulate to the first item from each, then the next item of each, etc.

Subproblem: define a proc that returns the first item from each nested sequence, and another that returns the remaining parts (accumulate-n will accumulate the former, and call itself with the latter):

 (define (select-cars sequence) 
   (map car sequence)) 
 (define (select-cdrs sequence) 
   (map cdr sequence)) 
 ;; Test 
 (define t (list (list 1 2 3) (list 40 50 60) (list 700 800 900))) 
 (select-cars t) 
 (select-cdrs t) 
 ;; Accumulates the result of the first and the already-accumulated 
 ;; rest. 
 (define (accumulate op initial sequence) 
   (if (null? sequence) 
       (op (car sequence) 
           (accumulate op initial (cdr sequence))))) 
 ;; accumulate-n 
 (define (accumulate-n op init sequence) 
   (define nil '()) 
   (if (null? (car sequence)) 
       (cons (accumulate op init (map car sequence)) 
             (accumulate-n op init (map cdr sequence))))) 
 ;; Usage: 
 (accumulate-n + 0 t) 

Originally I had (map (lambda (s) (car s)) sequence), but (lambda (s) (car s)) is just a function that returns car ...

Rather Iffy

But (lambda (s) (car s)) does not return car (the procedure) but the car of a pair. The notation (lambda (s) (car s)) shows the used operation in the mapping process more explicit.

 (define (accumulate-n op init seqs) 
   (if (null? (car seqs)) 
       (cons (accumulate op   init (map (lambda (s) (car s)) seqs)) 
             (accumulate-n op init (map (lambda (s) (cdr s)) seqs))))) 
 ;Maybe a helpful stepping stone. 
 ;Example in Mit-Scheme: 
 ;(user) => (map (lambda (s) (cdr s)) '((1 2 3) (4 5 6))) 
 ;Value: ((2 3) (5 6))