proglog

主にプログラミングに関する断片的メモ

howmsplit:ディレクトリ、fold系

findコマンドの部分をscemeで書くとしたら、file.utilに入ってるdirectory-foldというのを使うとよさそう。

Function: directory-fold path proc seed &keyword lister follow-link?

説明を見ると、ほとんどfindコマンドそのもののような感じ。
ディレクトリを渡すと、再帰的に探索して、ファイルのみをセットした関数に渡してくれるらしい。
でも、なんだか動き方が、具体的にはよく分からない。

で、

fold関数から入ってみる

Function: fold kons knil clist1

リストの要素に関数(2項演算子)を順番に作用させて、結果を貯めて返すみたいな働きらしい。
つまりは、(fold 2項演算子 初期値 対象リスト)

畳み込み関数の比較 (fold / accumulate / inject / reduce) - blanket logによると、SRFIのfoldは

(fold + 0 '(1 2 3))    ;  3 + (2 + (1 + 0)) = 6
(fold - 7 '(1 2 3))    ;  3 - (2 - (1 - 7)) = -5

こういう展開になる。
これは、上記サイトの表現だと、f が結果を右側に貯める

初期値、knilから初めて、対象リストの並びの左側から順番に適用。
計算結果、konsの返り値を2項演算子の右項として計算を進める。
そんな感じか。

(define (print-plus left right)
  (newline)
  (print "left: " left " : right: " right ":    =  " (+ left right))
  (+ left right))

(fold print-plus 0 '(1 2 3 4 5))

これの結果は

left: 1 : right: 0:    =  1

left: 2 : right: 1:    =  3

left: 3 : right: 3:    =  6

left: 4 : right: 6:    =  10

left: 5 : right: 10:    =  15
15

そしてkonsの最後の返り値が、全体の返り値になる。
足しておくなり、リスト化しておくなり。

この手のものの中では、前の反復の結果が渡ってくる、というのが特徴なのかな?
なんだろう、画像処理で、横のピクセルと比較して、色の変化幅を調節するようなフィルタとか。

directory-foldに戻る。

gaucheのマニュアルにあるサンプルで変数名だけ書き直して眺めてみる。

(use srfi-13) ;; for string-suffix?
(directory-fold "../"
                (lambda (entry result-accumulation)
		  (if (string-suffix? "~" entry)
		      (cons entry result-accumulation)
		      result-accumulation))
		'())

foldで言うkcons、ここで言うprocはフィルタ。
listerからくる要素に、一つずつ、反復適用される。
返り値に、各フィルタ結果を貯める処理を入れる。
フィルタ結果は右項に入って渡ってくる。
最後の返り値はフィルタの最後の反復の返り値。

howmsplitで使う場合は、副作用目的。
だから、渡されるファイルから正規表現で1日1ファイルをピックアップしてhowmsplit関数に渡す。
あとは捨てる。
ってだけでよさそう。