如何定义一个函数来反转Scheme中的列表,方法是使用foldr
and foldl
?
我们想要的是一个简洁的解决方案,使用foldl
调用并使用不同的解决方案foldr
调用,定义为:
(define (foldl operation lst initial)
(if (null? lst) initial
(foldl operation
(cdr lst)
(operation (car lst) initial))))
and
(define (foldr operation lst initial)
(if (null? lst) initial
(operation
(car lst)
(foldr operation (cdr lst) initial))))
聪明的人会观察到foldl
实现是尾递归的,因为返回值是在调用每个递归步骤时计算的 - 在最后一步,整个答案已经计算出来并简单地返回到链上。
The foldr
实现不是尾递归的,因为它必须使用递归链上传递回的值来构建返回值。
因此,我们感兴趣的两个Scheme实现应该采用以下形式,
(define (rev1 lst)
(foldl ___________________________
**Solution:**
(define (rev1 lst)
(foldl cons lst '()))
and
(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)
The foldl
解决方案应该相对简单(基于我们的直觉),但是foldr
解决方案可能需要更多的思考。
之前与此问题类似(但记录较少)的问题最终没有得到解答和/或关闭。