We next consider a DRS program that produces all possible pairings of elements of two lists. This involves the nested recursive procedures pairone and pairall. (pairone a l) pairs atom a with each of the elements of list l; (pairall l1 l2) produces all possible pairings of l1 and l2 by using pairone on successive elements of l1 and "gluing" the answer together with append.
(define pairone (lambda (a l) (if (null? l) () (cons (list a (car l)) (pairone a (cdr l)))))) (define pairall (lambda (l1 l2) (if (null? l1) () (append (pairone (car l1) l2) (pairall (cdr l1) l2)))))
The call (pairall '(1 2 3) '(a b c)) produces
((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c))
An APS version looks like this.
(define pairone-acc (lambda (a l acc-one) (if (null? l) acc-one (pairone-acc a (cdr l) (cons (list a (car l)) acc-one))))) (define pairall-acc (lambda (l1 l2 acc-all) (if (null? l1) acc-all (pairall-acc (cdr l1) l2 (append (pairone-acc (car l1) l2 ()) acc-all)))))
Since the order of the solution was not specified, this is acceptable. Unfortunately, there is another problem.
Let's try to "fold" the append into the process of building the accumulating parameter by reversing the order of events.
(define pairall-acc (lambda (l1 l2 acc-all) (if (null? l1) acc-all (pairone-acc (car l1) l2 (pairall-acc (cdr l1) l2 acc-all)))))