[ prog / sol / mona ]

prog


Scheme has no currying

5 2020-10-31 11:37

>>4
Currying actually refers to the transformation, where a function that takes multiple arguments is transformed into a series of functions that take only one argument and return the next function. It's pretty easy to do it by hand and if you have some way to figure out the arguments a procedure takes (SRFI 102, maybe?), you can do it automatically.

Here's a pretty ugly currying implementation for Guile that only works on functions that take at least one required argument and ignores optional arguments (including rest, I honestly have no idea how these could be handled):

(define (curry f)
  (let ((nargs (length (assoc-ref (procedure-arguments f) 'required))))
    ((let loop ((n nargs))
       (cond
        ((zero? n)
         (lambda (args)
           (apply f args)))
        (else
         (lambda (args)
           (lambda (v)
             ((loop (- n 1)) (append args (list v))))))))
     '())))

If you want to do it compile time, it's even easier (and actually portable!):

(define-syntax lambda-curry
  (syntax-rules ()
    ((_ () body body* ...)
     (begin body body* ...))
    ((_ (param params ...) body ...)
     (lambda (param) (lambda-curry (params ...) body ...)))))

;; Example: curried definition of map
(define curry-map
  (lambda-curry (f l)
    (cond
     ((null? l) l)
     (else (cons (f (car l)) ((curry-map f) (cdr l)))))))
6


VIP:

do not edit these