foldr
(向右折叠)基本上是按照存储在列表中的值从右到左的顺序执行递归计算。 foldl
与foldr
相反。我想知道人们是否可以使用foldr
实现功能foldl
?任何想法表示赞赏,在此先感谢。
答案 0 :(得分:3)
我想知道人们是否可以使用
foldr
来实现功能foldl
...
foldl
从左到右遍历该列表一次-它也是尾部递归的
(define (foldl f acc xs)
(if (null? xs)
acc
(foldl f
(f acc (car xs))
(cdr xs))))
foldr
遍历列表一次,将对f
的调用堆积到列表的最后一个元素–不是尾递归
(define (foldr f acc xs)
(if (null? xs)
acc
(f (foldr f acc (cdr xs))
(car xs))))
我们在下面验证其输出–
(foldl list 'init '(a b c))
;; '(((init a) b) c)
(foldr list 'init '(a b c))
;; '(((init c) b) a)
可以肯定,您可以使用foldr
和reverse
来实现foldl
,但这将遍历输入列表两次。每张折叠存在的原因是,您可以在任一方向上处理列表,而不必遍历一次...
答案 1 :(得分:0)
解决方案
在将所有参数传递给foldl
之前,只需反转输入列表:
(define (myfoldr func init-val lst)
(foldl func init-val (reverse lst)))
测试
第一:
(foldr (lambda (el acc) (list el acc))
'()
'(1 2 3 4 5))
;; => '(1 (2 (3 (4 (5 ())))))
(foldl (lambda (el acc) (list el acc))
'()
'(1 2 3 4 5))
;; => '(5 (4 (3 (2 (1 ())))))
现在:
(myfoldr (lambda (el acc) (list el acc))
'()
'(1 2 3 4 5))
;; => '(1 (2 (3 (4 (5 ())))))
foldl
由foldr
(define (myfoldl func initial-val lst)
(foldr func init-val (reverse lst)))
测试:
(myfoldl (lambda (el acc) (list el acc))
'()
'(1 2 3 4 5))
;; => '(5 (4 (3 (2 (1 ())))))