2.2.1 並びの表現

問題2.17

;; lのcdrが空リストならlのcarのリスト
;; そうでなければ、lのcdrのlast-pair
(define (last-pair l)
  (if (null? (cdr l))
      (list (car l))
      (last-pair (cdr l))))

問題2.18

;; 反復的('()はnil)
(define (reverse l)
  (define (iter l r)
    (if (null? l)
        r
        (iter (cdr l) (cons (car l) r))))
  (iter l '()))

;; 再帰的(効率悪)
(define (reverse l)
  (if (null? l)
      '()
      (append (reverse (cdr l)) (list (car l)))))

問題2.19

(define (first-denomination l) (car l))
(define (except-first-denomination l) (cdr l))
(define (no-more? l) (null? l))

coin-valuesの順はccの答に影響はない。なぜ?

問題2.20

(define (same-parity x . rest)
  (let ((xr (remainder x 2)))
    (define (recr l)
      (cond ((null? l) '())
            ((= xr (remainder (car l) 2))
             (cons (car l) (recr (cdr l))))
            (else (recr (cdr l)))))
    (cons x (recr rest))))
(same-parity 1 2 3 4 5 6 7) => (1 3 5 7)
(same-parity 0 1 2 3 4 5 6 7) => (0 2 4 6)

問題2.21

(define (square-list items)
  (if (null? items)
      '()
      (cons (* (car items) (car items))
            (square-list (cdr items)))))

(define (square-list items)
  (map (lambda (x) (* x x))
       items))

;; おまけ
(define (square-list items)
  (map * items items))

問題2.22

最初のsquare-listではリストの先頭の方の要素を先にconsし、後ろの方の要素を後にconsするので、順番が逆になる。
後の、square-listでは、answerがリストを構成していない。consでリストを作るには(cons 数値 リスト)としなければならないが、(cons リスト 数値)の順になっているためだ。

(square-list (list 1 2 3))

の結果を箱とポインタ記法で書くと

+-++-+  +-+
|*||*|->|9|
+-++-+  +-+
 |
+-++-+  +-+
|*||*|->|4|
+-++-+  +-+
 |
+-++-+  +-+
|/||*|->|1|
+-++-+  +-+

となる。しかし、

+-++-+  +-++-+  +-++-+
|*||*|->|*||*|->|*||/|
+-++-+  +-++-+  +-++-+
 |       |       |
+-+     +-+     +-+
|1|     |4|     |9|
+-+     +-+     +-+

となっているべきである。

問題2.23

(define (for-each proc l)
  (if (null? l)
      #t
      (begin (proc (car l))
             (for-each proc (cdr l)))))

gosh>  (for-each (lambda (x) (newline) (display x))
                 (list 57 321 88))
57
321
88
#t