まず、アキュムレータをインクリメントするのではなく、リストの各要素に同じ数を追加するだけなので、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)))]))
優れたコンパイラは、2 つの例と同じコードを生成する可能性が高いため、ほとんどの場合スタイルに依存します。お気づきのように、「左から左lambda
」のパターンは読みにくい可能性があるため、私はlet
.
map
ただし、演習 30.1.1 は、各例で発生する明示的な再帰の代わりとして使用しようとしています。あなたの例では使用map
していますが、一度に 1 つの追加のみを使用しているため、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
: の 1 行目はcond
空のチェックであり、2 行目は のへの再帰呼び出しに対する要素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
ます。
解決策を得るにはこれで十分です。ただし、最終的な答えを教えたくありません:)