Во-первых, я думаю, вы, возможно, путаете relative-2-absolute
с add-to-each
, поскольку add-to-each
просто добавляет одно и то же число к каждому элементу списка, а не увеличивает накопитель. Остальная часть этого поста предполагает, что это так, и просто снимает это увеличение.
Я думаю let
будет моим первым выбором для локального связывания. В вашем примере lambda
используется общий шаблон, который имитирует let
с использованием lambda
и приложение:
(let ([x e]) body)
Эквивалентно:
((lambda (x) body) e)
Если вы используете это преобразование из lambda
в let
в вашем примере, вы получите:
(define (add-to-each5 n a-list)
(cond
[(empty? a-list) empty]
[else (cons (let ([x n] [y a-list])
(first (map + (list (first y))
(list x))))
(add-to-each5 n (rest a-list)))]))
Хороший компилятор, вероятно, сгенерирует тот же код для этого, что и для двух ваших примеров, так что в основном все сводится к стилю. Как видите, шаблон «левый-левый lambda
» может быть более трудным для чтения, поэтому я предпочитаю let
.
Однако упражнение 30.1.1 пытается заставить вас использовать map
вместо явной рекурсии, которая встречается в каждом из ваших примеров. Вы используете map
в своем примере, но только для одного добавления за раз, что делает map
болезненным: зачем беспокоиться об окончании (list (first y))
и (list x)
, когда вы просто хотите (+ (first y) x)
?
Давайте посмотрим на простое определение map
, чтобы увидеть, как оно может быть полезным, а не болезненным, для этой проблемы:
(define (map f ls)
(cond
[(empty? ls) empty]
[else (cons (f (first ls)) (map f (rest ls)))]))
Сразу же вы должны заметить некоторые сходства с add-to-each
: первая строка cond
проверяет наличие пустых значений, а вторая строка cons
относится к элементу first
для рекурсивного вызова map
на rest
. Ключом является передача map
f
, который делает то, что вы хотите сделать, с каждым элементом.
В случае add-to-each
вы хотите добавить конкретный номер к каждому элементу. Вот пример добавления 2
:
> (map (lambda (n) (+ 2 n)) (list 1 2 3 4 5))
(3 4 5 6 7)
Обратите внимание, что и map
, и lambda
находятся здесь как 30.1.1 запросов, и они действуют на весь список без явной рекурсии исходного add-to-each
: рекурсия все абстрагируется в map
.
Этого должно быть достаточно, чтобы найти решение; Я не хочу давать окончательный ответ, хотя :)