Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution:
Generalized compose


; Return a function that applies f n times on its parameter. n >= 1. (define (self-compose* f n) (cond ((= n 1) f) ((> n 1) (lambda (x) (f ((self-compose* f (- n 1)) x)))) (else (error "self-compose*: n must be an integer larger than 0")))) ; Return a function that applies all functions to each other sequentially. The first function in f-list is applied as the last one. (define (compose* f-list) (cond ((= (length f-list) 1) (car f-list)) ((> (length f-list) 1) (lambda (x) ((car f-list) ((compose* (cdr f-list)) x)))) (else (error "compose* must be applied on a non-empty function list")))) ; Alternative, and more attractive variants: (define (self-compose* f n) (cond ((= n 1) f) ((> n 1) (compose f (self-compose* f (- n 1)))) (else (error "self-compose*: n must be an integer larger than 0")))) (define (compose* fn-lst) (cond ((= (length fn-lst) 1) (car fn-lst)) ((> (length fn-lst) 1) (compose (car fn-lst) (compose* (cdr fn-lst)))) (else (error "compose* must be applied on a non-empty function list")))) (define (curry2 f) (lambda(x) (lambda(y) (f x y)))) (define (reduce-right f lst) (if (null? (cdr lst)) (car lst) (f (car lst) (reduce-right f (cdr lst))))) ; An alternative implementation of compose* in terms of compose and reduce-right: (define (compose* fn-lst) (reduce-right compose fn-lst)) (define compose* ((curry2 reduce-right) compose)) (define (incr n) (+ n 1)) (define (fac n) (if (= n 0) 1 (* n (fac (- n 1))))) (define (compose f g) (lambda (x) (f (g x))))