####あーなるほど、foldl を二つの方向からやるようなものなんですね。自分で作ろうとしてうまくいってなかったんですが、foldl と foldr を同時にやるような物だと誤解してました。
#nobsun の fold を強引に mapAccum で書いたものです。
#fold で
#halve xs = (as,bs) where
((_,bs),(_,as)) = fold f ((0,xs),(0,[])) xs
f ((ny,ys),(nz,zs)) x = ((ny+1,ys'),(nz+1,zs')) where
(ys',zs') | ny <= nz = (tail ys, zs)
| otherwise = (ys, x:zs)
#と書けるときれいかなと思ったんですが無理(デッドロック)でした。
#bifoldl :: (a -> b -> a) -> (c -> b -> c) -> (a,c) -> [b] -> (a,c)
bifoldl f g (a,c) xs = (foldl' f a xs, foldl' g c (reverse xs))
fold' :: ((a,c) -> b -> (a,c)) -> (a,c) -> [b] -> (a,c)
fold' f (a,c) xs = bifoldl f_a f_c (a,c) xs
where
f_a a b = fst $ f (a,undefined) b
f_c c b = snd $ f (undefined,c) b
#要するにこういうことですよね
#しかし mapAccum 系が活用されてるの初めて見た気がします (無意味に複雑な気がして使ってなかったんですが) 見直したわー
#bifoldの第一引数 a -> b -> a は左からの蓄積なんだけど,右から畳み込みの結果を
反映できないですよね.第二引数 c -> b -> c は右からの畳み込みだけど,こちらは
左からの畳込みの結果を反映できないですよね.
#あ、そうですね。反対側からの畳み込みの結果に触ろうとしたら undefined になりますね、これはあかん