문제

계획 절차에서 "조기 반환"을 어떻게 할 수 있는지 알아 내려고 노력하고 있습니다. 없이 최상위를 사용합니다 if 또는 cond 구성처럼.

(define (win b)
 (let* ((test (first (first b)))
        (result (every (lambda (i) (= (list-ref (list-ref b i) i) test))
                       (enumerate (length b)))))
  (when (and (not (= test 0)) result) test))
 0)

예를 들어, 위의 코드에서 win 돌려 주다 test 만약 when 조건이 충족됩니다. 그렇지 않으면 0을 반환합니다. 그러나 발생하는 일은 절차가 언제나 결과에 관계없이 0을 반환합니다 when 상태.

내가이 방식으로 코드를 구성하는 이유는이 절차에서 수많은 복잡한 점검을해야하기 때문입니다 ( let* 예에서) 그리고 모든 것을 큰 cond 매우 다루기 어려울 것입니다.

도움이 되었습니까?

해결책

다음은 Call/CC를 사용하여 빌드하는 방법입니다. return 당신 자신.

(define (example x)
  (call/cc (lambda (return)
    (when (< x 0) (return #f))
    ; more code, including possible more calls to return
    0)))

일부 체계는 LEAT/CC라는 매크로를 정의하여 Lambda의 일부 소음을 떨어 뜨릴 수 있습니다.

(define (example x)
  (let/cc return
    (when (< x 0) (return #f))
    0))

물론 당신의 계획이 그렇지 않은 경우,/cc는 쓰기가 사소합니다.


Call/CC는 연속이라고 불리는 지점을 저장하기 때문에 작동합니다. 그것은 그 기능 인수로 계속 통과합니다. 함수가 계속 호출되는 경우, 스키마는 지금까지 쌓인 콜 스택 스택을 버리고 통화/CC 통화가 끝날 때까지 계속됩니다. 물론 함수가 연속을 호출하지 않으면 정상적으로 반환됩니다.

연속성은 해당 기능에서 반환을 시작하거나 글로벌 데이터 구조에 저장하여 나중에 전화 할 때까지 진정으로 마음을 구부리지 않습니다. 그렇지 않으면, 그것들은 다른 언어의 구조화 된 가토 진술과 같습니다 (/for/break/return/return/contink/sections/condations).


전체 코드가 어떻게 보이는지 모르겠지만 Cond와 함께 가서 복잡한 검사를 별도의 기능으로 고려하는 것이 좋습니다. 필요합니다 return 그리고 let* 일반적으로 지나치게 명령적인 코드의 증상입니다. 그러나 Call/CC 메소드는 현재 코드가 작동해야합니다.

다른 팁

한 가지 방법은 반복 대신 재귀를 사용하는 것입니다. 그런 다음 더 이상 재발하지 않음으로써 초기 출구가 달성됩니다.

"현재 연속으로 호출"지원을 사용하여 반품을 시뮬레이션 할 수 있습니다. 예제가 있습니다 위키 백과. 기능이 호출됩니다 통화-전류 연속, 종종 별명이 있지만 전화/cc 정확히 같은 것입니다. 약간 깨끗한 예도 있습니다 여기

참고 : 이것은 상당히 고급 체계 프로그래밍 기술이며 처음에는 약간의 마음을 구부릴 수 있습니다 ... !!!!

이 경우 당신은 언제를 원하지 않으며, 당신은 최상위 수준이 아니지만 if를 원합니다.

(define (win b)
  (let* ((test (first (first b)))
         (result (every (lambda (i) (= (list-ref (list-ref b i) i) test))
                        (enumerate (length b)))))
    (if (and (not (= test 0)) result) 
        test
        0)))

그것이 항상 0으로 돌아 오는 이유는 시대의 본체가 실행되었는지 여부에 관계없이 결과가 바닥에 떨어질 것이기 때문입니다. 알다시피, 함수 정의 형식에 암시적인 람다는 암시 적 시작 블록도 생성하므로

(define foo 
  (lambda (b)
     (begin
       (let ...)
       0)))

그리고 시작 방법은 마지막 양식의 결과를 내부에서 반환하는 동시에 모든 중간 결과를 바닥에 삭제한다는 것입니다. 이러한 중간 결과는 부작용을 갖기위한 것입니다. 당신은 그 중 어느 것도 사용하지 않지만 (!), (!),하지만 기능 정의 내부에 하나의 양식 (실제로 원하는 결과) 만 있으면주의해야합니다.

그렘

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top