ответ

3

Существует множество реализаций карри для Схемы - ни один из них не может быть столь же изящным, как Haskell, поскольку функции всегда являются унарными функциями, поэтому все может быть в карри. (Но это, конечно, может быть реализовано на достаточно мощной схеме, например, Racket.)

Что касается макроса, который вы выкопали - это довольно плохо: он использует не только антисанитарный макрос, но и вызывая eval явно и полагаясь на реализацию среды и т. д. Но это легко сделать с помощью простого макроса syntax-rules. AFAICT, это то, что он реализует:

(define-syntax-rule (clambda (x ... . r) b ...) 
    (let ([len (length '(x ...))] [real (lambda (x ... . r) b ...)]) 
    (let loop ([argss '()] [n 0]) 
     (lambda args 
     (let ([n (+ n (length args))] [argss (cons args argss)]) 
      (if (>= n len) 
      (apply real (apply append (reverse argss))) 
      (loop argss n))))))) 

Но здесь важное примечание. На странице, на которой вы ссылаетесь, говорит о том, что проблема версии функции заключается в том, что она явная - но она также имеет важное преимущество: при реализации макроса вы должны определить функцию с использованием clambda, тогда как функциональную версию можно использовать с любым встроенным функция. Во многих реализациях Схемы есть возможности для проверки возможности функции, и с ее помощью можно реализовать версию функции currying, которая знает, когда вызывать исходную функцию.

Смежные вопросы