ループの方向との違いはfoldl
ありますか?foldr
方向性だけでなく、彼らの行動にも違いがあると思いましたか?
1 に答える
たとえば、関数が結合法則でない場合(つまり、式をどのように括弧で囲むかが重要)、違いがあります
foldr (-) 0 [1..10] = -5
が、foldl (-) 0 [1..10] = -55
。
これは、前者がに等しい1-(2-(3-(4-(5-(6-(7-(8-(9-(10 - 0)))))))))
のに対し、後者はに等しいためです(((((((((0-1)-2)-3)-4)-5)-6)-7)-8)-9)-10
。
一方、(+)
結合法則(部分式を追加する順序は関係ありません)、
foldr (+) 0 [1..10] = 55
およびfoldl (+) 0 [1..10] = 55
。と同じ答えが得られる(++)
ため、は別の結合法則です(ただし、最初の法則の方が高速です。使用しないでください)。xs ++ (ys ++ zs)
(xs ++ ys) ++ zs
foldl (++)
一部の関数は一方向にしか機能しませんが、意味
foldr (:) :: [a] -> [a] -> [a]
がfoldl (:)
ありません。
Cale Gibbardの図(ウィキペディアの記事から)を見てください。f
真に異なるデータのペアで呼び出されることがわかります。
もう1つの違いは、リストの構造と一致するため、遅延評価に効率的であることが多く、2番目の引数(またはなど)で厳密でないfoldr
限り、無限リストで使用できることです。まれに良い選択です。使用している場合は、厳密であり、中間結果の長いリストを作成するのを妨げるため、通常は使用する価値があります。(このトピックの詳細については、この質問への回答をご覧ください。)f
(:)
(++)
foldl
foldl
foldl'