체계에서 카레 기능의 구현
-
21-08-2019 - |
문제
다음을 수행하면 어떻게됩니까?
(define ((func x) y)
(if (zero? y)
((func x) 1)
12))
나는 이것을 할 수 있다는 것을 이해한다 :
(define curried (func 5))
그리고 이제 나는 카레를 사용할 수 있습니다. 내가 궁금한 점은 함수의 정의에 있습니다. 라인을합니다
((func x) 1)
인수로 x를 가진 새 람다를 만들고 1에서 호출 하시겠습니까? 아니면 그보다 더 똑똑하고 기존의 것을 재사용합니다. (예를 들어, 내가하는 경우 (curried 0)
,, ((func x) 1)
선은 동일합니다 (curried 1)
- Plai 계획이 이것을합니까?)
해결책
체계 표준에서 그것은 지정됩니다
(define (f x) 42) is short for (define f (lambda (x) 42)) .
자연 (비표준) 일반화는 다음을 의미합니다.
(define ((f x) y) (list x y)) is short for (define (f x) (lambda (y) (list x y)))
which is short for (define f (lambda (x) (lambda (y) (list x y))))
그것을 테스트하려면 drscheme의 예제를 시도해 봅시다.
DrScheme, 버전 4.1.3.3-SVN5DEC2008 [3M]에 오신 것을 환영합니다. 언어 : 모듈; 메모리 제한 : 384 메가 바이트.
(정의 ((fx) y) (list xy)) (f 1)
((F 1) 2) (1 2)
임시 가치의 이름을 지정하면 어떤 일이 발생하는지 더 쉽게 알 수 있습니다.
(H (F 1)) (H 2) (1 2) (H 3) (1 3)
"PLAI Scheme"은 DrScheme에서 구현 되므로이 바로 가기 표기법을 물려받습니다.
다른 팁
계획을 가지고 일한 지 너무 오래 걸렸지 만 당신은 찾을 수 있습니다. 이 기사 도움이 되는. Lambda 표현의 암시 적 카레 정의를 허용하는 두 개의 매크로 인 C-Lambda 및 C-Define의 구현을 설명합니다.
Soegaard의 대답은 정확합니다. 이것은 전통적인 확장입니다. 그러나 Drscheme은 똑똑합니다!
다음 코드는 실행 시간과 동등한 것으로 밝혀졌습니다.
원본 출처 :
(define ((substitute lv value) e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons ((substitute lv value) f)
((substitute lv value) r))])]
[(cons? e)
(cons ((substitute lv value) (car e))
((substitute lv value) (cdr e)))]
[else e]))
최적화 시도 :
(define (substitute lv value)
(local ([define inner
(lambda (e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons (inner f)
(inner r))])]
[(cons? e)
(cons (inner (car e))
(inner (cdr e)))]
[else e]))])
inner))
이 기능을 크게 사용하는 코드 (한 번만가 아니라 여러 번)는 두 버전 모두에 대해 1800ms에서 실행됩니다. 더 흥미롭게 도이 버전 (무슨 일이 있었는지에 대한 내 시각화) :
(define (substitute lv value)
(local ([define inner
(lambda (e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons ((substitute lv value) f)
((substitute lv value) r))])]
[(cons? e)
(cons ((substitute lv value) (car e))
((substitute lv value) (cdr e)))]
[else e]))])
inner))
2000ms에서 실행됩니다. 따라서 대체품 내에서 대체 요청이 각각 람다를 생성한다면 분명히 느리게 진행되지만 바로 가기 표기법의 경우에는 그렇지 않은 것으로 보입니다.