SICP 全笔记

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 (首次使用时,是 initialsequence 的最后一个元素作为输入),得到的结果与前一个 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))))