Gauche本勉強メモ(5日目)

6.4 foldの定義

foldの定義を書いてみる。
自力で考えてみるか。

10分くらいゴニョゴニョやってみたがわからんかった。

正解は

(define (fold proc init lis)
  (if (null? lis)
	  init
	  (fold proc (proc (car lis) init) (cdr lis))))

まずlisが空リストの時になぜinitをそのまま返せば良いのかわからん。
procが

(lambda (a b) a)

みたいな手続きだったらどうなるの?

試してみるか。
まず、さっき自前のfold定義しちゃったからgaucheの組み込みのfoldを呼べるように戻すには以下のようにすればいいらしい。

gosh> (define fold (with-module gauche fold))
fold

で、試してみる。

gosh> (fold (lambda (a b) a) 1 '(2 3 4 5))
5
gosh> (fold (lambda (a b) a) 1 '())
1

あ、ほんとだ。空リスト渡したときはinitが返って来てる。うーん、、なんか空リストなんかが返って来そうな気がするんだけど。。

次に、再帰の部分が完成させられなかった。再帰を使うんだろうなと思って、ゴニョゴニョしてたのだけど正解に辿り着けなかった。慣れなのかな?

プリントデバッグ

今日読んだところにプリントデバッグの方法が書いてあった。
#?=を書くと、実行中にその式の評価した値を表示するらしい。

(define (fold proc init lis)
  (if (null? lis)
	  init
	  (fold proc #?=(proc (car lis) init) #?=(cdr lis))))

gosh> (fold (lambda (a b) a) 1 '(2 3 4 5))
#?="(stdin)":13:(proc (car lis) init)
#?-    2
#?="(stdin)":13:(cdr lis)
#?-    (3 4 5)
#?="(stdin)":13:(proc (car lis) init)
#?-    3
#?="(stdin)":13:(cdr lis)
#?-    (4 5)
#?="(stdin)":13:(proc (car lis) init)
#?-    4
#?="(stdin)":13:(cdr lis)
#?-    (5)
#?="(stdin)":13:(proc (car lis) init)
#?-    5
#?="(stdin)":13:(cdr lis)
#?-    ()
5

これは便利。


今日はここまで。