Неявное каррирование в Scheme с синтаксическими правилами? - PullRequest
5 голосов
/ 19 сентября 2010

Джеффри Менье имеет неявный макрос Карри здесь , который использует defmacro Мне было интересно, если кто-то когда-либо писал это с синтаксическими правилами?

1 Ответ

3 голосов
/ 25 сентября 2010

Существует множество реализаций карри для Scheme - ни одна из них не может быть столь же элегантной, как 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, тогда как функциональную версию можно использовать с любымвстроенная функция.Во многих реализациях Scheme есть средства для проверки арности функции, и с ее помощью можно реализовать версию функции каррирования, которая знает, когда вызывать исходную функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...