Racket에서 람다 만 사용하여 재귀를 만드는 방법은 무엇입니까?

cv14

람다 만 사용하여 아래 코드를 재귀 적으로 만드는 방법을 알아 내려면 도움이 필요합니다.

(define (mklist2 bind pure args)
  (define (helper bnd pr ttl lst)
    (cond [(empty? lst) (pure ttl)]
          [else (define (func t) (helper bnd pr (append ttl (list t)) (rest lst)))
           (bind (first lst) func)])
    )
  (helper bind pure empty args))

감사합니다

샘플 fact구두 프로그램이 주어지면 -

(define fact
  (lambda (n)
    (if (= n 0)
        1
        (* n (fact (- n 1)))))) ;; goal: remove reference to `fact`

(print (fact 7)) ; 5040

위의 내용 fact(lambda (n) ...)호출 fact할 때이 람다를 요청하여 새로운 인수로 다시 적용 할 수 있습니다. lambda이름이없고 최상위 define바인딩을 사용할 수없는 경우 변수를 바인딩하는 유일한 방법은 람다의 매개 변수를 사용하는 것 입니다. 다음과 같은 것을 상상해보십시오.

(lambda (r)
  ; ...lambda body...
  ; call (r ...) to recur this lambda
)

우리는해야 할 something우리의 할 (lambda (r) ...)행동하라 이런 식으로 -

(something (lambda (r)
  (print 1)
  (r)))

; 1
; 1
; 1
; ... forever

이것은 결합 자에 something아주 가깝습니다 U-

(define u
  (lambda (f) (f f)))

(define fact
  (lambda (r)     ;; wrap in (lambda (r) ...)
    (lambda (n)
      (if (= n 0)
          1
          (* n ((r r) (- n 1))))))) ;; replace fact with (r r)

(print ((u fact) 7))

; => 5040

그리고 지금 재귀 매개 변수의 사용을 통해 무슨 일이 일어나고 있는지, 우리는 효과적으로 모두 제거 할 수 define바인딩 만 사용하여 쓰기 lambda-

; ((u fact) 7)
(print (((lambda (f) (f f))  ; u
         (lambda (r)         ; fact
           (lambda (n)
             (if (= n 0)
                 1
                 (* n ((r r) (- n 1)))))))
        7))

; => 5040

U-combinator는 간단하지만 ((r r) ...)함수 내에서 호출해야하는 것은 번거 롭습니다. (r ...)직접 재귀 호출 할 수 있다면 좋을 것 입니다. 이것이 바로 Y-combinator가하는 일입니다.

(define y
  (lambda (f)
    (f (lambda (x) ((y f) x))))) ;; pass (y f) to user lambda

(define fact
  (lambda (recur)
    (lambda (n)
      (if (= n 0)
          1
          (* n (recur (- n 1))))))) ;; recur directly

(print ((y fact) 7))

; => 5040

그러나 y이름 별 재귀 정의가 어떻게 있는지 보십니까? 를 사용 u하여 이름 별 참조를 제거하고 lambda대신 매개 변수를 사용하여 반복 할 수 있습니다 . 위에서했던 것과 동일합니다.

(define u
  (lambda (f) (f f)))

(define y
  (lambda (r)      ;; wrap in (lambda (r) ...)
    (lambda (f)
      (f (lambda (x) (((r r) f) x)))))) ;; replace y with (r r)

(define fact
  (lambda (recur)
    (lambda (n)
      (if (= n 0)
          1
          (* n (recur (- n 1)))))))

(print (((u y) fact) 7)) ;; replace y with (u y)

; => 5040

우리는 이제 사용하여 쓸 수 있습니다 lambda-

; (((u y) fact) 7)
(print ((((lambda (f) (f f))   ; u
          (lambda (r)          ; y
            (lambda (f)
              (f (lambda (x) (((r r) f) x))))))
         (lambda (recur)       ; fact
           (lambda (n)
             (if (= n 0)
                 1
                 (* n (recur (- n 1)))))))
        7))

; => 5040

커링을 사용하여 필요한 경우 더 많은 매개 변수를 지원하도록 기능을 확장 할 수 있습니다.

(define range
  (lambda (r)
    (lambda (start)
      (lambda (end)
        (if (> start end)
            null
            (cons start ((r (add1 start)) end)))))))

(define map
  (lambda (r)
    (lambda (f)
      (lambda (l)
        (if (null? l)
            null
            (cons (f (car l))
                  ((r f) (cdr l))))))))

(define nums
  ((((u y) range) 3) 9))

(define squares
  ((((u y) map) (lambda (x) (* x x))) nums))

(print squares)
; '(9 16 25 36 49 64 81)

그리고 하나의 lambda표현으로-

; ((((u y) map) (lambda (x) (* x x))) ((((u y) range) 3) 9))
(print (((((lambda (f) (f f)) ; u
           (lambda (r)        ; y
             (lambda (f)
               (f (lambda (x) (((r r) f) x))))))
          (lambda (r)         ; map
            (lambda (f)
              (lambda (l)
                (if (null? l)
                    null
                    (cons (f (car l))
                          ((r f) (cdr l))))))))
         (lambda (x) (* x x))) ; square
        (((((lambda (f) (f f)) ; u
            (lambda (r)        ; y
              (lambda (f)
                (f (lambda (x) (((r r) f) x))))))
           (lambda (r)         ; range
             (lambda (start)
               (lambda (end)
                 (if (> start end)
                     null
                     (cons start ((r (add1 start)) end)))))))
          3)   ; start
         9)))  ; end

; => '(9 16 25 36 49 64 81)

lazyy사용 하는 멋진 구현을 확인하세요.

#lang lazy

(define y
  (lambda (f)
    (f (y f))))
#lang lazy

(define y
  ((lambda (f) (f f)) ; u
   (lambda (r)
     (lambda (f)
       (f ((r r) f))))))
#lang lazy

(define y
  ((lambda (r)
    (lambda (f)
      (f ((r r) f))))
  (lambda (r)
    (lambda (f)
      (f ((r r) f))))))

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

defaultdict를 사용하여 람다 함수로 사전을 만드는 방법은 무엇입니까?

분류에서Dev

jflex에서 람다 기호를 만드는 방법은 무엇입니까?

분류에서Dev

다른 보고서를 사용하여 SSRS에서 보고서를 만드는 방법은 무엇입니까?

분류에서Dev

PostgreSQL에서 필드를 사용하여 다각형을 만드는 방법은 무엇입니까?

분류에서Dev

C ++ shared_ptr에서 람다를 삭제 자로 사용하여 객체 캐시를 만드는 방법은 무엇입니까?

분류에서Dev

Autofixture에서 다른 소스를 사용하여 개체를 만드는 방법은 무엇입니까?

분류에서Dev

이진 트리를 생성하는 재귀 메서드를 만드는 방법은 무엇입니까?

분류에서Dev

@XmlElements를 사용하여 동일한 목록에 다른 개체를 만드는 방법은 무엇입니까?

분류에서Dev

재귀를 사용하여 나선형 정사각형 행렬을 만드는 방법은 무엇입니까?

분류에서Dev

R에서 재귀를 사용하여 길이가 n 인 모든 2 ^ n 이진 시퀀스의 행렬을 만드는 방법은 무엇입니까?

분류에서Dev

RxJs 연산자를 사용하여 재귀 HTTP 호출을 만드는 방법은 무엇입니까?

분류에서Dev

다른 사람 사이에 새 파일 이름을 삽입하는 bash에서 함수를 만드는 방법은 무엇입니까?

분류에서Dev

Android에서 백그라운드 프로세스 및 알람 관리자를 사용하여 알림 메시지를 만드는 방법은 무엇입니까?

분류에서Dev

sqlalchemy를 사용하여 추가 조인 인수를 사용하여 일대 다에서 일대일 접근자를 만드는 방법은 무엇입니까?

분류에서Dev

Java에서 스레드를 만드는 사람을 찾는 방법은 무엇입니까?

분류에서Dev

메서드를 만들고 다른 클래스에서 사용하는 방법은 무엇입니까?

분류에서Dev

각도 재질을 사용하여 드롭 다운 내부에 트리 뷰를 만드는 방법은 무엇입니까?

분류에서Dev

mklink 명령을 사용하여 Windows에서 하드 링크를 만드는 방법은 무엇입니까?

분류에서Dev

반응에서 formik을 사용하여 동적 드롭 다운을 만드는 방법은 무엇입니까?

분류에서Dev

JavaScript에서 Object.create ()를 사용하여 HTML DOM 노드를 만드는 방법은 무엇입니까?

분류에서Dev

phonegap / cordova를 사용하여 입력 드롭 다운 메뉴를 만드는 방법은 무엇입니까?

분류에서Dev

phonegap / cordova를 사용하여 입력 드롭 다운 메뉴를 만드는 방법은 무엇입니까?

분류에서Dev

((KeyboardEvent)-> dynamic) 유형의 람다를 만드는 방법은 무엇입니까? Kotlin에서

분류에서Dev

((KeyboardEvent)-> dynamic) 유형의 람다를 만드는 방법은 무엇입니까? Kotlin에서

분류에서Dev

Rails 4.0.x에서 람다와 관계를 만드는 방법은 무엇입니까?

분류에서Dev

netbeans를 사용하여 많은 Java 클래스에서 jar를 만드는 방법은 무엇입니까?

분류에서Dev

Win Explorer를 사용하여 Windows의 Ubuntu에서 Bash 용 폴더를 만드는 방법은 무엇입니까?

분류에서Dev

Win Explorer를 사용하여 Windows의 Ubuntu에서 Bash 용 폴더를 만드는 방법은 무엇입니까?

분류에서Dev

징을 사용하여 WPF에서 여러 DropHandler를 만드는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    defaultdict를 사용하여 람다 함수로 사전을 만드는 방법은 무엇입니까?

  2. 2

    jflex에서 람다 기호를 만드는 방법은 무엇입니까?

  3. 3

    다른 보고서를 사용하여 SSRS에서 보고서를 만드는 방법은 무엇입니까?

  4. 4

    PostgreSQL에서 필드를 사용하여 다각형을 만드는 방법은 무엇입니까?

  5. 5

    C ++ shared_ptr에서 람다를 삭제 자로 사용하여 객체 캐시를 만드는 방법은 무엇입니까?

  6. 6

    Autofixture에서 다른 소스를 사용하여 개체를 만드는 방법은 무엇입니까?

  7. 7

    이진 트리를 생성하는 재귀 메서드를 만드는 방법은 무엇입니까?

  8. 8

    @XmlElements를 사용하여 동일한 목록에 다른 개체를 만드는 방법은 무엇입니까?

  9. 9

    재귀를 사용하여 나선형 정사각형 행렬을 만드는 방법은 무엇입니까?

  10. 10

    R에서 재귀를 사용하여 길이가 n 인 모든 2 ^ n 이진 시퀀스의 행렬을 만드는 방법은 무엇입니까?

  11. 11

    RxJs 연산자를 사용하여 재귀 HTTP 호출을 만드는 방법은 무엇입니까?

  12. 12

    다른 사람 사이에 새 파일 이름을 삽입하는 bash에서 함수를 만드는 방법은 무엇입니까?

  13. 13

    Android에서 백그라운드 프로세스 및 알람 관리자를 사용하여 알림 메시지를 만드는 방법은 무엇입니까?

  14. 14

    sqlalchemy를 사용하여 추가 조인 인수를 사용하여 일대 다에서 일대일 접근자를 만드는 방법은 무엇입니까?

  15. 15

    Java에서 스레드를 만드는 사람을 찾는 방법은 무엇입니까?

  16. 16

    메서드를 만들고 다른 클래스에서 사용하는 방법은 무엇입니까?

  17. 17

    각도 재질을 사용하여 드롭 다운 내부에 트리 뷰를 만드는 방법은 무엇입니까?

  18. 18

    mklink 명령을 사용하여 Windows에서 하드 링크를 만드는 방법은 무엇입니까?

  19. 19

    반응에서 formik을 사용하여 동적 드롭 다운을 만드는 방법은 무엇입니까?

  20. 20

    JavaScript에서 Object.create ()를 사용하여 HTML DOM 노드를 만드는 방법은 무엇입니까?

  21. 21

    phonegap / cordova를 사용하여 입력 드롭 다운 메뉴를 만드는 방법은 무엇입니까?

  22. 22

    phonegap / cordova를 사용하여 입력 드롭 다운 메뉴를 만드는 방법은 무엇입니까?

  23. 23

    ((KeyboardEvent)-> dynamic) 유형의 람다를 만드는 방법은 무엇입니까? Kotlin에서

  24. 24

    ((KeyboardEvent)-> dynamic) 유형의 람다를 만드는 방법은 무엇입니까? Kotlin에서

  25. 25

    Rails 4.0.x에서 람다와 관계를 만드는 방법은 무엇입니까?

  26. 26

    netbeans를 사용하여 많은 Java 클래스에서 jar를 만드는 방법은 무엇입니까?

  27. 27

    Win Explorer를 사용하여 Windows의 Ubuntu에서 Bash 용 폴더를 만드는 방법은 무엇입니까?

  28. 28

    Win Explorer를 사용하여 Windows의 Ubuntu에서 Bash 용 폴더를 만드는 방법은 무엇입니까?

  29. 29

    징을 사용하여 WPF에서 여러 DropHandler를 만드는 방법은 무엇입니까?

뜨겁다태그

보관