Exercise 2.38. The accumulate procedure is also known as fold-right, because it combines the first element of the sequence with the result of combining all the elements to the right. There is also a fold-left, which is similar to fold-right, except that it combines elements working in the opposite direction:
(define (fold-left op initial sequence)
(define (iter result rest)
(if (null? rest)
result
(iter (op result (car rest))
(cdr rest))))
(iter initial sequence))
What are the values of
(fold-right / 1 (list 1 2 3))
(fold-left / 1 (list 1 2 3))
(fold-right list nil (list 1 2 3))
(fold-left list nil (list 1 2 3))
Give a property that op should satisfy to guarantee that fold-right and fold-left will produce the same values for any sequence.
对于题目中的几个操作,我们可以从下面几个角度来看:
(fold-right / 1 (list 1 2 3))
(/ 1 (/ 2 (/ 3 1))) 最初的 1 被放在了最后。
(fold-left / 1 (list 1 2 3))
(/ (/ (/ 1 1) 2) 3) 最初的 1 与 list 中第一个元素做完除法之后的结果与 list 中的第二个元素进行除法操作,以此类推之后的操作。
(fold-right list '() (list 1 2 3))
(list 1 (list 2 (list 3 ‘())))
(fold-left list '() (list 1 2 3))
(list (list (list ‘() 1) 2) 3)
如果要让 fold-left 与 fold-right 得到相同的结果,那么我们要保证 op 对参数的顺序是不能有要求的。
对于除法来说 x/y 不等于 y/x,所以两个结果不同。
对于 list 来说,x/y 不等于 y/x,所以两个结果不同。
比如我们可以对加法进行 fold 的运算
(fold-left + 0 '(1 2 3 4 5)) ; 15
(fold-right + 0 '(1 2 3 4 5)) ; 15