foldr
とを使用して、Scheme でリストを反転する関数をどのように定義できますfoldl
か?
必要なのは、Scheme で呼び出しを使用してリストを逆にする簡潔なソリューションと、定義されている呼び出しfoldl
を使用した別のソリューションです。foldr
(define (foldl operation lst initial)
(if (null? lst) initial
(foldl operation
(cdr lst)
(operation (car lst) initial))))
と
(define (foldr operation lst initial)
(if (null? lst) initial
(operation
(car lst)
(foldr operation (cdr lst) initial))))
鋭い人はfoldl
、各再帰ステップが呼び出されるたびに返される値が計算されるため、実装が末尾再帰であることに気付くでしょう。
このfoldr
実装は末尾再帰ではありません。これは、再帰チェーンに戻された値を使用して戻り値を構築する必要があるためです。
したがって、関心のある 2 つの Scheme 実装は、次の形式である必要があります。
(define (rev1 lst)
(foldl ___________________________
**Solution:**
(define (rev1 lst)
(foldl cons lst '()))
と
(define (rev2 lst)
(foldr ___________________________
**Solution 1:**
(define (rev2 lst)
(foldr
(lambda (element accumulator)
(foldr cons accumulator (cons element '())))
lst '()))
**Solution 2:**
(define (rev2 lst)
(foldr
(lambda (element accumulator)
(append accumulator (cons element '())))
lst '()))
最終的な目標は、以下を呼び出すことができるようにすることです。
(rev1 '(1 2 3)) -> (3 2 1)
(rev2 '(1 2 3)) -> (3 2 1)
解決策は(foldl
私たちの直感に基づいて) 比較的単純なものですが、foldr
解決策にはおそらくもう少し検討が必要です。
この質問に似た (ただし文書化されていない) 以前の質問は、未回答またはクローズされました。