PowerShellでfoldr(アール)
概要
foldlの時
http://d.hatena.ne.jp/kya-zinc/20091128
と同じように、
パイプから流れてきたオブジェクトをスクリプトブロックでたたみこむ。
実装
function Main { 1,2,3 | foldr {$_l + $_r * 100} 4 1,2,3 | foldr_stack {$_l + $_r * 100} 4 $null | foldr {$_l + $_r} 100 $null | foldr_stack {$_l + $_r} 100 } function foldr([ScriptBlock] $script, [Object] $last) { $_r = $last $input_arr = @() + $input for($idx = $input_arr.Length - 1; $idx -ge 0; $idx--) { $_l = $input_arr[$idx] $_r = & $script } $_r } function foldr_stack([ScriptBlock] $script, [Object] $last) { begin { $stack = New-Object System.Collections.Stack } process { $stack.push($_) } end { $_r = $last while($stack.Count -ne 0) { $_l = $stack.Pop() $_r = & $script } $_r } } . Main
実行結果
4030201 4030201 100 100
パイプ入力をすべて待ってから動作するので、
ストリーム処理っぽくない。
"@() + $input"の部分は列挙子(イテレータ?)を配列にするテクニック。
配列のインデックスを逆にたどる(foldr)のが気に入らなかったので
スタックでストリームを裏返してみた。(foldr_stack)
スタックのempty判定が見つからなかった…。