LoginSignup
0
0

More than 5 years have passed since last update.

SICP読書録 #22 2.2.1(続き)リストに対するマップ - 練習問題 2.23

Last updated at Posted at 2018-12-22

hiroshi-manabe様の日本語訳を使わせてもらいます。
練習問題等はGaucheで実行。

前回はこちら

リストに対するマップ

リストの全要素に指定した係数を掛けるという手続き。

_.scm
(define nil ())

(define (scale-list items factor)
  (if (null? items)
    nil
    (cons (* (car items) factor)
    (scale-list (cdr items) factor))))
_.scm
gosh> (scale-list (list 1 2 3 4 5) 10)
(10 20 30 40 50)

リストの全要素に何かをする、という抽象的な手続きmapを作ってみよう。

_.scm
(define (map proc items)
  (if (null? items)
    nil
    (cons (proc (car items))
          (map proc (cdr items)))))

mapを使えば、scale-list手続きは次のように書き直せる。

_.scm
(define (scale-list items factor)
  (map (lambda (x) (* x factor)) items))

練習問題2.21

リストの要素を2乗する手続きを作ろう。まずはmapを使わずに。

_.scm
(define (square-list1 items)
  (if (null? items)
    nil
    (cons (square (car items)) (square-list (cdr items)))))

続いて、mapを使う方法。

_.scm
(define (square-list2 items)
  (map (lambda (x) (square x)) items))

動かしてみよう。

_.scm
gosh> (square-list1 (list 1 2 3 4 5))
(1 4 9 16 25)
gosh> (square-list2 (list 1 2 3 4 5))
(1 4 9 16 25)

練習問題 2.22

square-lit手続きを反復プロセス化したつもり。

_.scm
(define (square-list items)
  (define (iter things answer)
    (if (null? things)
      answer
      (iter (cdr things)
            (cons (square (car things)) answer))))
  (iter items nil))

動かしてみよう・・・あれれ?

_.scm
gosh> (square-list (list 1 2 3))
(9 4 1)

逆になるのも当然だ。次のように結果のリストが作られるからだ。

_.scm
> (cons (square 1) nil)    => (1)
> (cons (square 2) '(1))   => (4 1)
> (cons (square 3) '(4 1)) => (9 4 1)

ならば、こうだ。consの引数を逆にしてみる。

_.scm
(define (square-list-fix items)
  (define (iter things answer)
    (if (null? things)
      answer
      (iter (cdr things)
            (cons answer (square (car things))))))
  (iter items nil))

動かしてみよう。

_.scm
gosh> (square-list-fix (list 1 2 3))
(((() . 1) . 4) . 9)

ダメかー。そりゃそうだ。次のことが行われる。

_.scm
> (cons nil (square 1))             => (() . 1)
> (cons '(() . 1) (square 2))       => ((() . 1) . 4)
> (cons '((() . 1) . 4) (square 3)) => (((() .  1) . 4) . 9)

練習問題 2.23

手続きをそれぞれの要素に適用していくだけの手続きfor-eachを作ろう。begin使ってもいいよね・・・

_.scm
(define (for-each proc items)
  (if (null? items)
    #t
    (begin
      (proc (car items))
      (for-each proc (cdr items)))))

実行結果。

_.scm
gosh> (for-each
        (lambda (x) (newline) (display x))
        (list 57 321 88))

57
321
88#t
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0