sicp(10)m2.21〜2.24

(更新したのは、3日です)

;;練習
(define one (lambda (f) (lambda (x) (f x))))
(define (inc x) (+ x 1))
(define two (lambda (f) (lambda (x) (f (f x)))))
(define add (lambda (f1 f2)
              (lambda (g)
                (lambda (x) ((f2 g)((f1 g) x))))))

(define (reverse lst)
  (define (iter result lst)
    (if (null? (cdr lst))
        (cons (car lst) result)
        (iter (cons (car lst) result) (cdr lst))))
  (iter '() lst))
;	gosh> (reverse '(1 2 3 4))
;	(4 3 2 1)

;;写す。
(define (scale-list items factor)
  (if (null? items)
      '()
      (cons (* (car items) factor)
            (scale-list (cdr items) factor))))
;	gosh> (scale-list (list 1 2 3 4) 10)
;	(10 20 30 40)
;;この辺は何も考えなくても理解できる。

(define (my_map proc items)
  (if (null? items)
      '()
      (cons (proc (car items))
            (map proc (cdr items)))))
;	gosh> (my_map (lambda (x) (* x x)) (list 1 2 3))
;	(1 4 9)

;;本当のmapはもっと便利。
;	gosh> (map (lambda (x y) (+ x (* y 2)))
;	           (list 1 2 3)
;	           (list 4 5 6))
;	(9 12 15)

;;mapを使ったscale-list
(define (scale-list items factor)
  (map (lambda (x) (* x factor)) items))

;;m2.21
;;悩むことなく終了。
(define (square-list items)
  (if (null? items)
      '()
      (cons ((lambda (x) (* x x)) (car items))
            (square-list (cdr items)))))
;	gosh> (square-list (list 1 2 3))
;	(1 4 9)

;;次はmap版。こちらも簡単。
(define (square-list2 items)
  (map (lambda (x) (* x x)) items))
;	gosh> (square-list2 (list 3 2 1))
;	(9 4 1)

;;m2.22
(define (square x) (* x x))
(define (square-list2.22 items)
  (define (iter things answer)
    (if (null? things)
        answer
        (iter (cdr things)
              (cons (square (car things))
                    answer))))
  (iter items '()))
;;確かに逆順。
;	gosh> (square-list2.22 (list 1 2 3))
;	(9 4 1)
;;理由はconsでリストの←方向に追加していってるから。

;;次は期待どおり動かない方
(define (square-list2.22+ items)
  (define (iter things answer)
    (if (null? things)
        answer
        (iter (cdr things)
              (cons answer
                    (square (car things))))))
  (iter items '()))
;;実行結果はこんな感じ。
;	gosh> (square-list2.22+ (list 1 2 3))
;	(((() . 1) . 4) . 9)
;;上手く表示させるには、以下のようにする。
;;(a b c) = (cons a (cons b (cons c '())))
;;でも、問の関数の場合は、以下のようになっている。
;;(cons (cons (cons '() a) b) c)
;;だから、上手く行かない。(反復プロセス?での解決策は現在模索中です><)

;;m2.23
(define (for-each f lst)
  (f (car lst))
  (cond ((null? (cdr lst))
         (f '()))
        (else
         (for-each f (cdr lst)))))
;;ちょっと出力が違うけど、こんな感じかな?
;	gosh> (for-each (lambda (x) (newline) (display x))
;	          (list 57 321 88))
;	
;	57
;	321
;	88
;	()#<undef>

;;2.2.2
(define x (cons (list 1 2) (list 3 4)))
;;lengthももともと存在していた。
;	gosh> (length x)
;	3
(define (count-leaves lst)
  (cond ((null? lst) 0)
        ((not (pair? lst)) 1)
        (else (+ (count-leaves (car lst))
                 (count-leaves (cdr lst))))))
;	gosh> (count-leaves x)
;	4

;;m2.24
;;こんな感じかな?
;;(1 (2 (3 4))) 
;;  |
;;|===|
;;1 |====|
;;  2  |===|
;;     3   4
;	gosh> (list 1 (list 2 (list 3 4)))
;	(1 (2 (3 4)))
;;