Карри в схеме

У меня есть это curry функция:

(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))

Я думаю это как (define curry (f a b)),

мое задание - написать функцию consElem2All с помощью curry, Который должен работать как

(((consElem2All cons) 'b) '((1) (2 3) (4)))
>((b 1) (b 2 3) (b 4))

Я написал эту функцию регулярно:

(define (consElem2All0 x lst) 
  (map (lambda (elem) (cons x elem)) lst))

но до сих пор не знаю, как преобразовать его с curry, Может кто-нибудь мне помочь?

заранее спасибо

bearzk

4 ответа

Решение

Вы должны начать с чтения о карри. Если вы не понимаете, что такое карри, его может быть очень трудно использовать... В вашем случае, http://www.engr.uconn.edu/~jeffm/Papers/curry.html может быть хорошим Начните.

Одним из наиболее распространенных и интересных применений каррирования является использование таких функций, как Reduce или Map (для себя или своих аргументов).

Давайте определим два оператора каррирования!

(define curry2 (lambda (f) (lambda (arg1) (lambda (arg2) (f arg1 arg2)))))
(define curry3 (lambda (f) (lambda (arg1) (lambda (arg2) (lambda (arg3) (f arg1 arg2 arg3))))))

Затем несколько карри математических функций:

(define mult (curry2 *))
(define double (mult 2))

(define add (curry2 +))
(define increment (add 1))
(define decrement (add -1))

И тогда наступит карри уменьшить / карту:

(define creduce (curry3 reduce))
(define cmap (curry2 map))

Используя их

Сначала уменьшите случаи использования:

(define sum ((creduce +) 0))
(sum '(1 2 3 4)) => 10

(define product (creduce * 1))
(product '(1 2 3 4)) => 24

А затем карту вариантов использования:

(define doubles (cmap double))
(doubles '(1 2 3 4)) => (2 4 6 8)

(define bump (cmap increment))
(bump '(1 2 3 4)) => (2 3 4 5)

Я надеюсь, что это поможет вам понять полезность карри...

Итак, ваша версия карри принимает функцию с двумя аргументами, скажем:

(define (cons a b) ...)

и превращает это в то, что вы можете назвать так:

(define my-cons (curry cons))
((my-cons 'a) '(b c)) ; => (cons 'a '(b c)) => '(a b c)

У вас на самом деле есть функция, которая принимает три аргумента. Если бы у вас был curry3 что бы управлять 3-мя функциями, вы могли бы сделать что-то вроде:

(define (consElem2All0 the-conser x lst) ...)

(как вы сделали, но позволяя использовать функции, похожие на минусы, кроме минусов!)

и затем сделайте это:

(define consElem2All (curry3 consElem2All0))

У вас нет такого curry3 под рукой. Таким образом, вы можете либо создать его, либо обойти его, "вручную" каррируя дополнительную переменную самостоятельно. Работа вокруг выглядит примерно так:

(define (consElem2All0 the-conser)
  (lambda (x lst) ...something using the-conser...))
(define (consElem2All the-conser)
  (curry (consElem2All0 the-conser)))

Обратите внимание, что есть еще одно возможное использование карри в самом выражении карты, подразумеваемое тем, что вы оборачиваете лямбду вокруг cons, чтобы передать элемент в cons. Как ты мог карри x в cons так что вы получите функцию с одним аргументом, которую можно использовать непосредственно для отображения?...

Возможно, лучше использовать обобщенную версию:

      (define (my-curry f)
  (lambda args
    (cond ((= (length args) 1)
             (lambda lst (apply f (cons (car args) lst))))
          ((>= (length args) 2)
             (apply f (cons (car args) (cdr args)))))))
(define (consElem2All0 x lst) 
  (map ((curry cons) x) lst))
Другие вопросы по тегам