Отговори (3)
Разглеждайки 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)))
Тези две неща са еднакви:
((lambda (p1 p2...) body) v1 v2...)
и
(let ((p1 v1) (p2 v2)...) body)
Нека разгледаме два прости случая, за да можем да разберем как можем да пренапишем всяка функция, която използва 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.
- Сега за повече от един 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))
Така че сега ние оценяваме всеки от ламбда изразите, като им даваме стойност, а най-вътрешният ламбда израз се грижи за това, което искаме да изчислим, използвайки имената на променливите, които са присвоени на всеки ламбда израз.
Надяваме се, че това беше ясно и може да помогне на другите да видят по-ясно!