combine
은 이진 연산자 bin
으로 목록을 축소해야하지만 술어 pred?
에 실패한 값을 찾으면 exc
을 반환해야하며 이러한 값을 찾으면 목록에서 계산을 수행하면 안됩니다.Racket에서 call/cc의 재미있는 동작을 설명하는 방법은 무엇입니까?
이것은 계속되는 간단한 문제입니다.
#lang racket
(define (id x)
x)
(define (const x)
(lambda (_) x))
(define (combine pred? bin zero exc)
(call/cc
(lambda (exit)
(letrec
((f (lambda (xs)
(if (empty? xs)
zero
(if (pred? (first xs))
(exit exc)
(bin (first xs) (f (rest xs))))))))
f))))
(define product
(combine zero?
*
1
0))
(product '(1 2 3 0 4))
코드는 거의 작동하지만 아주 미묘한 오류가 있습니다.
그것은 다음과 같은 예외가 발생 :
define-values: assignment disallowed;
cannot re-define a constant
constant: product
일을 쉽게 만들 수 있습니다. 단지 작은 변화가 필요하다 :
(define (combine pred? bin un zero exc)
(lambda (ys)
(call/cc
(lambda (exit)
(letrec
((f (lambda (xs)
(if (empty? xs)
zero
(if (pred? (first xs))
(exit exc)
(bin (first xs) (f (rest xs))))))))
(f ys))))))
나는 문제가 라켓 정의의 연속 함수를 정의하는 것입니다,하지만 사람이 더 자세한 정보를 줄 수있는 것을 볼? 예를 들어 어떤 신택스 변형이 관련 되었습니까? 여기에 있어야 순서의
이것은 체계 자체로 설명 할 수 있습니까, 아니면 구현에서 언어 외부를 봐야합니까? –
@Rdgstv'#lang racket'은 표준을 따르지 않지만, [호환 가능] 것으로 보인다 (http://www.r6rs.org/final/html/r6rs/r6rs-ZH-14.html#node_idx_352). 구현 책임 : 구현시의 연속이 두 번 이상 호출됨을 감지해야합니다. 구현에서이를 감지하면 조건 유형 및 어설 션으로 예외를 발생시켜야합니다. "*. Racket (구현)은 많은 표준 Scheme 보고서 언어를 지원합니다. 동일한 primitive로'define'과'set! '을 가진 많은 "scheme"구현물을 보았습니다. –
Sylwester
@Rdgstv'call/cc'에 관해서는. 모든'call/cc'는 연속을 함수로 드러내는 것입니다. 많은 Scheme 구현체가 어쨌든 CPS로 코드를 변환하지만'call/cc '에서는 코드를 변환하지 않습니다. CPS'call/cc'는 단지'(define (call/cc body c) (body (람다 (실제 값의 연속) (c 값))) c))'입니다. 'define '과 같은 특별한 형식은 CPS에서하기가 어렵습니다. 함수 내에서 최상위 바인딩을 정의하는 프리미티브가 없기 때문입니다. (함수 안에서'define '은'letrec'가되고 그것은 우리가 원하는 것이 아닙니다) – Sylwester