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

Exercise solution:
Generalization of curry-2 and curry-3


Here is a solution with some explaining comments. The curry function was suggested by Søren Envoldsen (student in the PP 2013 class).

; f is a function with n parameters. Return a curried version of f. ; Søren Enevoldsen, Sept. 12, 2013: (define (curry f n) (curry-internal f n '())) ; This function generates a nesting of lambda expression, each accepting a single parameter. ; While nesting lambda expressions (lambda (x) ...) into each other we form a list of all parameters in the last parameter. ; When all nested lambda expressions have been formed, (reverse args) is the list of parameters. f is applied on (reverse args). ; Sample rewritings, currying -: ; (curry - 3) => ; (curry-internal - 3 ()) => ; (lambda(x) (curry-internal - 2 (list x))) => ; (lambda (x) (lambda (y) (curry-internal - 1 (list y x)))) => ; (lambda (x) (lambda (y) (lambda (z) (apply - (reverse (list z y x)))))) (define (curry-internal f n args) (if (= n 1) (lambda (x) (apply f (reverse (cons x args)))) (lambda (x) (curry-internal f (- n 1) (cons x args))))) ; The following variant of uncurry has been suggested by KN: ; The function cf is a curried function with n levels of parameters. ; Return an uncuried variant of cf that - flatly - accepts n parameters. (define (uncurry cf n) (lambda pars (if (= (length pars) n) (apply-n n cf pars) (error "Illegal function signature")))) ; This function successively applies the curried functions. ; parameters holds the remaing parameter list, to be used step-wise by the forthcoming calls of the single-parameter functions. ; At each level, a lambda expression is applied on the first element of parameters. The tail of parameters is passed to the next call of apply-n. (define (apply-n n cf parameters) (if (= n 1) (cf (car parameters)) (apply-n (- n 1) (cf (car parameters)) (cdr parameters))))

Here are some example uses:

> (define cp4 (curry + 4)) > ((((cp4 1) 2) 3) 4) 10 > (define p4 (uncurry cp4 4)) > (p4 1 2 3 4) 10 > (p4 1 2 3 4 6 7 8) Illegal function signature > (p4 1 2 3) Illegal function signature > (define x (uncurry (curry + 4) 4)) > (x 1 2 3 4) 10 > (x 1 2 3 4 5) Illegal function signature