理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

問題2-82を解く準備をする

自力で解くことにする。がんばる!!


自分で解くのに、なんとなくfor-eachを使ってみたかったんだけど、

Function: for-each proc list1 list2 …

[R5RS] 手続きprocをリストの各エレメントに対して順に適用します。 procの結果は捨てられます。for-eachの戻り値は定義されていません。複数のリストが与えられた場合、一番短いリストが終了した時点でfor-eachは終了します。

Gauche ユーザリファレンス: 6.14 ベクタ

なんかよく分からない。procの結果が捨てられるとはどういうことなんだろう。

(for-each + (list 1 2 3)) ; #<undef>

あれ、予想では6が出てくるはずだったんだけど!
次printでやってみる。

gosh> (for-each print (list 1 2 3))
1
2
3
#<undef>

むー。

分かったこと。

第2引数で渡される関数はリストの各要素に適用されるけど、その結果(これがprocの結果)が捨てられる。
そうか、そう考えるとドキュメントの意味そのままか。

ホントはこんな感じに使うのかな

各リストから1番目の要素を取ってきて関数を適用、2番目の要素を取ってきて関数を適用、という具合に使うっぽい。結果を捨てるってことは関数の副作用を使うのが目的なのかな。

gosh> (for-each (lambda (x y) (print (* x y))) (list 1 2 3) (list 4 5 6))
4
10
18
#<undef>

apply使うのか

そっか、さっきのはapplyを使うべきところだった。

(for-each + (list 1 2 3)) ; ダメ
(apply + (list 1 2 3)) ; 6

とりあえずfor-eachの使い方がなんとなくわかってきた。
そして今回の問題では使いにくいかなということも分かってきた。
ホントはfor-eachの結果が配列で戻ってくるみたいなのが欲しかったんだけど。

(I-want + (list 1 2 3) (list 4 5 6)) ; (5 7 9) こういうのが欲しい

作った

(define (for-each-map func list1 list2)
  ; list1とlist2のサイズが等しいことが前提
  (if (null? list1)
      '()
      (cons (func (car list1) (car list2))
	    (for-each-map func (cdr list1) (cdr list2)))))

(for-each-map + (list 1 2 3 4) (list 5 6 7 8)) ; (6 8 10 12)

今日はとりあえずこれでおしまい。明日またがんばる。