SICP独習会 リストの写像(問題2.21〜)


ここではリストの各要素に対して、なんらかの作用させる手続きを定義する。例として、

  • リストの各要素の値を、n倍する手続きscale-list
  • scale-listをより抽象化した手続きmap

が定められている。

問題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))

問題2.22

traceしてみた結果、


CALL iter (1 2 3 4) ()
CALL iter (2 3 4) (1)
CALL iter (3 4) (4 1)
CALL iter (4) (9 4 1)
CALL iter () (16 9 4 1)
RETN iter (16 9 4 1)
RETN iter (16 9 4 1)
RETN iter (16 9 4 1)
RETN iter (16 9 4 1)
RETN iter (16 9 4 1)
(16 9 4 1)
のようになった。つまり、consを前の方からつめていくので、逆順になる。

また、その逆にしたら


((((() . 1) . 4) . 9) . 16)
先頭に空リストが来てしまい、きちんとしたリストにならない。

問題2.23

最初、このようなコードを書いたのだが、

(define (my-for-each proc lst)
  (if (null? lst)
    0
    ((proc (car lst))
     (my-for-each proc (cdr lst)))))

述語ifは、複文にできないらしい。なので、述語condを使って定義した。

(define (my-for-each proc lst)
  (cond
    ((null? lst) 0)
    (else (proc (car lst))
          (my-for-each proc (cdr lst)))))