Exercise 2.33. Fill in the missing expressions to complete the following definitions of some basic list-manipulation operations as accumulations:
(define (map p sequence)
(accumulate (lambda (x y) <??>) nil sequence))
(define (append seq1 seq2)
(accumulate cons <??> <??>))
(define (length sequence)
(accumulate <??> 0 sequence))
从这里练习开始,后面很大一部分练习都需要用到 accumulate,所以这个练习的目的是熟悉 accumulate 的功能。
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
accumulate 中的 op 是一个有两个参数的过程。使用 accumulate 的思路如下:对 sequence 中的元素 由后往前 依次使用 op (首次使用时,是 initial 与 sequence 的最后一个元素作为输入),得到的结果与前一个 sequence 的元素又作为 op 的输入,一直到 sequence 的第一个元素为止。
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
(define (new-map p sequence)
(accumulate (lambda (x y)
(cons (p x) y))
'()
sequence))
(define (new-append seq1 seq2)
(accumulate cons seq2 seq1))
(define (new-length sequence)
(accumulate (lambda (x y)
(1+ y))
0 sequence))
而测试则可以使用 scheme 的内建过程来进行结果的验证
(load "../testframe.scm")
(assertequal? (new-map (lambda (x) (+ x 1))
'(1 2 3 4 5))
(map (lambda (x) (+ x 1))
'(1 2 3 4 5)))
(assertequal? (new-append '(1 2 3 4) '(5 6 7))
(append '(1 2 3 4) '(5 6 7)))
(assertequal? (new-length '(1 2 (3 4)))
(length '(1 2 (3 4))))