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関数に渡す。
あとは捨てる。
ってだけでよさそう。