foldl
定義
code:1.hs
foldl :: (a -> b -> a) -> a -> b -> a
foldl f e [] = e
foldl f e (x:xs) = foldl f (f e x) xs
fold left
code:hs
1 : (2 : (3 : []))) -- 通常のリスト
(((0 + 1) + 2) + 3) -- foldl (+) 0 1,2,3
使用例
code:hs
sum' :: Int -> Int
sum' xs = foldl (+) 0 xs
関連
foldl1
foldl'
foldM
#WIP
Foldable型クラスのmethodとしての定義
1.hsより一般化されているmrsekut.icon
code:hs
foldl :: (a -> b -> a) -> a -> t b -> a
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
foldrの定義と見比べてみると、いくつか余分なものを加えた形に見える
code:hs
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo . f) t) z
https://gyazo.com/6dc5c306c6b5f7a1e47021a83246eeee
グレーの部分を取り除くと、foldrになる
https://xtech.nikkei.com/it/article/COLUMN/20091009/338681/?P=3
「foldrとfoldlの間にある双対定理」と「Dual型によって定義されるmappendの双対」の二つの双対が使われています
もっかい読みたいmrsekut.icon
リストから数値や逆順のリストを出力する関数と相性が良い ref
パフォーマンス的に
例えば、sumとかlengthとかreverseとか
reverseは配列生成じゃんmrsekut.icon
末尾再帰である
foldl' f (f e x) xsの()の部分が先に計算され、
「末尾の処理」はfoldl' f ■ xsとなっているため、これは末尾再帰
パフォーマンスの話
foldl'との関係
https://kazu-yamamoto.hatenablog.jp/entry/20110908/1315473844
https://qiita.com/autotaker1984/items/09c5ceaa13e9077f5359
https://xtech.nikkei.com/it/article/COLUMN/20070403/267180/
定義にseq関数が使われている?
だから正格評価になっている?
hackage見た感じ、そんな感じはしないけど
https://stackoverflow.com/questions/6872898/what-is-weak-head-normal-form/6889335#6889335
http://tanakh.jp/posts/2014-04-07-foldl-is-broken.html
foldlはこわれているのでなおす
基本的にfoldlではなく、foldl'を使うという話もある