2009-03-29 14 views
3

Я использую лекции и текст SICP, чтобы узнать о Scheme самостоятельно. Я рассматриваю упражнение, в котором говорится: «Применение выражения E является выражением формы (E E1, ... En). Это включает случай n = 0, соответствующий выражению (E). E является либо применением E, либо применением Curried application of E. "Новичок: Выполненные функции в схеме

(Edit:. Я исправил выше цитату ... Я изначально исказили определение)

Задача состоит в том, чтобы определить приложение выделанной процедуры, которая принимает значение 3 для

(define foo1 
    (lambda (x) 
     (* x x))) 

Я действительно не понимаю идею здесь, и чтение статьи в Википедии о Curriying действительно не помогло.

Может ли кто-нибудь помочь с более ясным объяснением того, что просят здесь?

На самом деле даже дать мне ответ на эту проблему было бы полезно, так как после этого еще пять нужно решить. ... Я просто не понимаю основную идею.

Дополнение: Даже после длинного объяснения Брайана Кэмпбелла, я все еще несколько потерян.

Является ли (foo1 (sqrt 3))) рассмотренным приложением foo и, следовательно, карри-приложение foo?

кажется слишком простым, но может быть ...

Typing (((foo1 2)) 2) в DrScheme дает следующую ошибку (я вроде ожидаемый)

procedure application: expected procedure, given: 4 (no arguments) 

После перечитывания What is Currying? я понимаю, что я также могу повторно -define foo1 быть:

(define (foo1 a) 
    (lambda (b) 
     (* a b))) 

Итак, я могу ввести

((foo1 3) 4) 

Но это на самом деле не получить меня ближе к производству 3 в качестве выходного сигнала, и кажется, что это на самом деле не выделки оригинальный foo1, это просто повторно определение Это.

Черт, 20 лет программирования C не подготовил меня к этому. :-) :-)

+0

У вас есть несбалансированные двойные кавычки. Куда заканчивается ваша цитата? – Svante

+0

Я обновил свой ответ с некоторыми разъяснениями и ответами на ваши изменения. Попытайтесь не думать о других определениях Currying, которые вы видите; это упражнение не означает определение функции Curried, но вместо этого применяется функция Curried. –

+0

Пожалуйста, дайте мне знать, помог ли мой отредактированный ответ! Поскольку вы пытаетесь это узнать, я пытаюсь дать вам достаточно информации для решения проблемы, не решая ее самостоятельно; если вы хотите, чтобы я расширил свое объяснение вообще, я, конечно, согласен. –

ответ

7

Хм, эта проблема довольно смутно сформулирована, по сравнению с обычно более понятным стилем книг. На самом деле, похоже, что вы можете ошибочно задать проблему, если у вас проблема с here; что может способствовать вашей путанице.

Я сломаю определение для вас, с некоторыми примерами, которые могут помочь вам понять, что происходит.

Приложение выражения E является выражением формы (E E1 ... En).

Вот пример заявки:

(foo 1 2)  ; This is an application of foo 
(bar 1)  ; This is an application of bar 

Это включает в себя случай п = 0, что соответствует выражению (Е).

(baz)   ; This is an application of baz 

каррированного Применение Е является либо приложением Й или применение каррированной применении E & # 56319; ...........

Это тот, который вы неправильно цитировали; выше - определение из набора проблем, которое я нашел в Интернете.

Существует две половины этого определения. Начиная с первым:

каррированным Применением Е является либо применением Е

(foo 1 2)  ; (1) A Curried application of foo, since it is an application of foo 
(bar 1)   ; (2) A Curried application of bar, since it is an application of bar 
(baz)   ; (3) A Curried application of baz, since it is an application of baz 

или применение каррированного применения Х

((foo 1 2) 3) ; (4) A Curried application of foo, since it is an application of (1) 
((bar 1))  ; (5) A Curried application of bar, since it is an application of (2) 
((baz) 1 2)  ; (6) A Curried application of baz, since it is an application of (3) 
(((foo 1 2) 3)) ; A Curried application of foo, since it is an application of (4) 
(((bar 1)) 2) ; A Curried application of bar, since it is an application of (5) 
       ; etc... 

Помогает ли вам помощь, с которой вам нужно начинать?

Редактировать: Да, (foo1 (sqrt 3)) - Попытка использования foo1; это так просто. Это не очень хороший вопрос, поскольку во многих реализациях вы фактически получите 2.9999999999999996 или что-то в этом роде; невозможно получить значение, которое вернет ровно 3, если только ваша схема не имеет своего рода представления точного algebraic numbers.

Ваш второй пример - действительно ошибка. foo1 возвращает целое число, которое недействительно для применения. Это лишь некоторые из более поздних примеров, для которых справедлив рекурсивный случай применения приложения функции. Посмотрите, например, на foo3.

Редактировать 2: Я только что проверил в SICP, и похоже, что понятия здесь не объясняются до раздела 1.3, в то время как в этом задании упоминается раздел 1.1. Я бы рекомендовал прочитать раздел 1.3, если вы еще этого не сделали.

+0

Я ценю ваш длинный ответ, но признаюсь, что я все еще довольно озадачен. Я отредактировал вопрос, чтобы отразить мое текущее состояние замешательства :-) – Leonard

+0

@Brian. См. Мой комментарий в исходном вопросе. Спасибо. – Leonard

3

См What is 'Currying'?

Карринг принимает функцию и обеспечивает новую функцию принимающую один аргумент и возвращающегося указанную функцию с первым аргументом набор к этому аргументу.

+0

Спасибо. Я прочитал этот вопрос перед публикацией, но сейчас перечитал его, и это стало более понятным во второй раз. – Leonard

2

Я думаю, вы слишком много сбиваете с толку. Вычисление функции принимает функцию типа F (a1, a2, ... aN) и превращает ее в F (a1), которая возвращает функцию, которая принимает a2, (которая возвращает функцию, которая принимает a3 ... и т. Д.)

Так что если у вас есть:

(define F (lambda (a b) (+ a b))) 
(F 1 2) ;; ==> 3 

вы можете снискать это сделать что-то, что действует как следующее:

(define F (lambda (a) (lambda (b) (+ a b)))) 
((F 1) 2) ;; ==> 3 

в случае Вашего конкретного вопроса, это кажется очень запутанной.

(foo1 (sqrt 3)) 

кажется подходящим. Я бы рекомендовал оставить его сейчас и прочитать больше книги.


вы можете сделать функцию, которая делает простой Карри для вас:

(define (curry f x) (lambda (y) (apply f (cons x y)))) 
(curry = 0) ;; a function that returns true if input is zero 
+0

Кажется, что вы столкнулись с некоторыми скобками вокруг лямбда. – Svante

+0

Благодарим вас за '((F 1) 2)' часть. Помог мне разобраться с карри! –

3

Я не думаю, что функция Карри Джеймс правильно - есть ошибка синтаксиса, когда я пытаюсь его в моем схема переводчика.

Вот реализация «кэрри», который я использую все время:

> (define curry (lambda (f . c) (lambda x (apply f (append c x))))) 
> ((curry list 5 4) 3 2) 
(5 4 3 2) 

Обратите внимание, он также работает для выделки более одного аргумента в функцию.

Там же макрос кто-то написал, что позволяет вам писать функции, которые неявно Карри для вас, когда вы называете их с недостаточными аргументами: http://www.engr.uconn.edu/~jeffm/Papers/curry.html

+0

+1. Я предпочитаю вашу функцию, даже если я правильно набрал свою работу, работает лучше. И я должен был проверить, что мои функции работали, извините. –

+0

Ссылка не работает. – ceving

0

В зависимости от реализации схемы, могут быть некоторые утилиты, чтобы иметь возможность восстановить из ошибок/исключений, например, в Chicken Scheme, есть condition-case.

(condition-case (func) 
    ((exn) (print "error"))) 

Мы можем определить функцию, которая взять функцию произвольного числа элементов и возвращает curryed форму:

(define curry 
    (lambda (func . args) 
     (condition-case (apply func args) 
      ((exn) 
       (lambda plus 
        (apply curry func (append args plus)))))])))) 

Это немного некрасиво, потому что если вы используете слишком много аргумент одно время , вы никогда не получите окончательного результата, но это превратит любую функцию в карри-форму.

3

Большинство ответов, которые вы получили, являются примерами «частичной оценки». Чтобы сделать истинное currying в Схеме, вам нужна синтаксическая помощь. Как например:

(define-syntax curry 
    (syntax-rules() 
    ((_ (a) body ...) 
    (lambda (a) body ...)) 
    ((_ (a b ...) body ...) 
    (lambda (a) (curry (b ...) body ...))))) 

который затем использовать как:

> (define adding-n3 (curry (a b c) (+ a b c))) 
> (define adding-n2-to-100 (adding-n3 100)) 
> ((adding-n2-to-100) 1) 10) 
111 

> (adding-n3 1) 
#<procedure> 

> ((adding-n3 1) 10) 
#<procedure> 

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

  • Нет связанных вопросов^_^