используя лямбду вместо пустых схем - PullRequest
7 голосов
/ 25 мая 2010

В SICP 1.2.1 есть функция, которая делает рациональное число следующим образом:

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

Мне просто любопытно, как вы можете реализовать то же самое, используя лямбду вместо let, не вызывая GCD дважды. Я не мог понять это сам.

Ответы [ 4 ]

13 голосов
/ 25 мая 2010

Глядя на SICP раздел 1.3.2 ,

(let ((<var1> <exp1>)
      (<var2> <exp2>)
      ...
      (<varn> <expn>))
   <body>)

эквивалентно

((lambda (<var1> ...<varn>)
    <body>)
 <exp1>
 ...
 <expn>)

Итак, ваша процедура,

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

должно быть эквивалентно

(define (make-rat n d)
  ((lambda (g)
    (cons (/ n g) (/ d g)))
  (gcd n d)))
10 голосов
/ 25 мая 2010

Эти две вещи одинаковы:

((lambda (p1 p2...) body) v1 v2...)

и

(let ((p1 v1) (p2 v2)...) body)
1 голос
/ 03 июня 2013

Давайте рассмотрим два простых случая, чтобы мы могли понять, как мы можем переписать любую функцию, которая использует let с лямбдой:

  1. В нашем первом случае у нас есть один let. Эта функция очень проста, она возвращает заданный вход, добавляя к нему 10:

    (define (test x)
      (let ((b 10))
        (+ x b)))
    

Теперь давайте превратим это в выражение, использующее лямбду:

    (define (test-lambda x)
      ((lambda (b)
         (+ x b))
       10))

Как видите, test-lambda возвращает лямбда-оценку, которая оценивается со значением 10. Тестируя это, мы можем сказать:

    (test-lambda 10)

, который вернет 20.

  1. Теперь для более чем одного let мы вкладываем лямбда-выражения в лямбда-выражения.

В нашем случае let у нас есть два оператора let:

    (define (lets x)
      (let ((a 10)
            (b 20))
        (+ x a b)))

Мы можем написать это с лямбдой так:

    (define (lets-lambda x)
      ((lambda (a)
         ((lambda (b)
            (+ x a b))
          20))
       10))

Итак, теперь мы оцениваем каждое из лямбда-выражений, давая им значение, а самое внутреннее лямбда-выражение заботится о том, что мы хотим вычислить, используя имена переменных, которым было присвоено каждое лямбда-выражение.

Надеюсь, это было ясно и могло бы помочь другим увидеть более ясно!

1 голос
/ 22 февраля 2011
(define-syntax let-as-lambda
  (syntax-rules ()
        ((_ (x value) body)
            (let ((x value))
              body))))

(printf "~s~n" (let-as-lambda (x 1) (+ x 1)))
...