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 (首次使用时,是 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))))