2009-03-29 3 views
3

저는 SICP 강의와 텍스트를 사용하여 Scheme에 대해 배우고 있습니다. 나는 "식 E의 적용은 식 (E E1, ... En)의 표현입니다. 이것은 식 (E)에 해당하는 n = 0의 경우를 포함합니다. Curried 응용 프로그램 E의 응용은 E의 응용이거나 E의 Curried 응용의 응용 "초급 : Scheme의 카 트리 함수

(편집 :. 내가 원래 정의를 잘못 인용했던 ... 위의 견적을 수정)

작업은

(define foo1 
    (lambda (x) 
     (* x x))) 
에 대한 3로 평가 절차의 카레 응용 프로그램을 정의하는 것입니다

나는 정말로 여기에 대한 생각을 이해하지 못하고, Curriying에 대한 Wikipedia 항목을 읽는 것이 도움이되지 못했습니다.

누구에게 문의해야하는지에 대해 더 명쾌하게 설명 할 수 있습니까?

실제로 나에게이 문제에 대한 답을 주더라도 도움이 될 것입니다. ... 나는 단지 기본 아이디어를 얻지 못하고있다.

추가 : Brian Campbell의 긴 설명을 한 후에도 여전히 다소 분실 상태입니다.

(foo1 (sqrt 3)))은 foo의 응용 프로그램으로 간주되므로 foo의 카레 응용 프로그램입니까? (I 가지 예상되는)

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

What is Currying?을 다시 읽은 후 나는 또 다시 할 수 이해

도 간단한데,하지만 어쩌면 ... DrScheme에 (((foo1 2)) 2)를 입력하면

다음과 같은 오류를 제공합니다 -define foo1은가되게합니다 : 그래서

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

그때 입력 할 수 있습니다

((foo1 3) 4) 

12

그러나 이것은 정말 출력으로 삼을 생산하는 가까이 저를하지 않으며,이 정말 원래 foo1은 무두질되지 않는 것처럼, 그냥있어 다시 정의를 보인다 그것.

젠장, 20 년 동안의 C 프로그래밍은 나를 위해 준비하지 못했습니다. :-) :-)

+0

: 예처럼 :로

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

당신은 그 때 사용한다. 견적은 어디에서 끝나나요? – 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 

이 식 (E)에 대응하는 n 개의 경우도 포함 = 0. ...........

;

(baz)   ; This is an application of baz 

E의 커리 어플리케이션 E의 애플리케이션 또는 E & # 56319의 카레 애플리케이션의 애플리케이션 중 하나 인

이것은 잘못 인용 한 것입니다. 위의 정의는 내가 온라인에서 찾은 문제 집합의 정의입니다.

이 정의에는 두 개의 절반이 있습니다. 제부터는 : E의 커리 어플리케이션 E

(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... 
E의 카레 애플리케이션의 애플리케이션 중

이다

도움이 필요 하신가요?

편집 : 예, (foo1 (sqrt 3))은의 Curried 응용 프로그램입니다. 그렇게 간단합니다. 이는 많은 구현에서 실제로 2.9999999999999996 또는 그와 비슷한 것을 얻을 것이므로 매우 좋은 질문은 아닙니다. Scheme에 정확히 algebraic numbers의 일종의 표현이 없으면 정확히 3을 반환하는 값을 가질 수 없습니다.

두 번째 예는 실제로 오류입니다. foo1은 정수를 반환하며 적용 할 수 없습니다. 함수의 응용 프로그램을 적용한 재귀 적 경우가 유효한 이후 예제 중 일부만입니다. 예를 들어 foo3을 살펴보십시오.

편집 2 : 방금 SICP를 확인 했으므로 여기서는 개념이 섹션 1.3까지 설명되지 않은 것처럼 보입니다.이 과제에는 섹션 1.1 만 언급되어 있습니다. 아직 섹션 1.3을 읽으려고하는 것이 좋습니다.

+0

길게 대답 하겠지만 고맙습니다. 상당히 당혹 스럽다. 나는 현재의 혼란 상태를 반영하기 위해 질문을 편집했다 :-) – Leonard

+0

@ 브라이언. 원래 질문에 대한 내 의견을 참조하십시오. 고마워. – Leonard

3

What is 'Currying'?

커링 함수를 취하고 새로운 기능 단일 인자를 수용하고, 그 인수에 설정 첫번째 인수로 지정된 복귀 기능을 제공 참조.

+0

감사합니다. 게시하기 전에 그 질문을 읽었지 만 지금 다시 읽었습니다. 두 번째로 더 의미가 있습니다. – Leonard

2

나는 혼란 스럽다고 생각합니다. 함수를 커링하는 것은 F (a1, a2, ... aN) 타입의 함수를 취하여 a2를 취하는 함수를 반환하는 F (a1)로 바꿉니다 (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

'((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

당신의 계획 구현에 따라, 거기에 몇 가지 유틸리티 수 있습니다 복구 할 수 있도록 오류/예외 (예 : 치킨 계획)의 경우 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

대부분의 답변은 '부분 평가'의 예입니다. Scheme에서 실제 currying을 수행하려면 구문 도움말이 필요합니다. 당신은 불균형 따옴표가

> (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>