Is difference between foldl and foldr just the direction of looping? I thought there was a difference in what they did, not just in the direction?

• I'm curious what you were reading that confused you. A link might have made the question more clear. Looks like @AndrewC has a quality answer for you though. Nov 7 '12 at 23:51
• You'll also find a very nice answer here stackoverflow.com/questions/3082324/… Nov 8 '12 at 1:45
• the difference is that their argument functions have their arguments order respectively flipped: the one fit for foldl combines result with list element type; and one for foldr combines list element type with result. Nov 12 '12 at 16:43
• @WillNess a difference is that the accumulating functions have flipped types. foldr f doesn't have to be foldl (flip f) Nov 13 '12 at 21:42
• @AndrewC thank you, that's what I meant, yes. Nov 14 '12 at 6:51

There's a difference if your function isn't associative (i.e. it matters which way you bracket expressions) so for example,
foldr (-) 0 [1..10] = -5 but foldl (-) 0 [1..10] = -55.
This is because the former is equal to 1-(2-(3-(4-(5-(6-(7-(8-(9-(10 - 0))))))))), whereas the latter is (((((((((0-1)-2)-3)-4)-5)-6)-7)-8)-9)-10.

Whereas because (+) is associative (doesn't matter what order you add subexpressions),
foldr (+) 0 [1..10] = 55 and foldl (+) 0 [1..10] = 55. (++) is another associative operation because xs ++ (ys ++ zs) gives the same answer as (xs ++ ys) ++ zs (although the first one is faster - don't use foldl (++)).

Some functions only work one way:
foldr (:) :: [a] -> [a] -> [a] but foldl (:) is nonsense.

Have a look at Cale Gibbard's diagrams (from the wikipedia article); you can see f getting called with genuinely different pairs of data: Another difference is that because it matches the structure of the list, foldr is often more efficient for lazy evaluation, so can be used with an infinite list as long as f is non-strict in its second argument (like (:) or (++)). foldl is only rarely the better choice. If you're using foldl it's usually worth using foldl' because it's strict and stops you building up a long list of intermediate results. (More on this topic in the answers to this question.)

• Another difference, related to the last point, is that foldl can never return if given an infinite list, whereas foldr will if given a function that is non-strict in its second argument (such as (:) or const, ...) Nov 8 '12 at 2:41
• foldl has argument order flipped compared to foldr. So all functions work both ways: foldl (flip (:)) still typechecks. Nov 9 '12 at 10:22
• some sidenotes:  another way to talk about it is to mention type asymmetry of (:) :: a->[a]->[a] or flip (:) :: [a]->a->[a] which dictates the only possible order of combination.  scanl is somewhere "between" foldl and foldr, combining the "looping from the left" with possibility to stop early. Nov 12 '12 at 17:10
• There's a semantic not just syntactic difference, though: foldr (:) "!" "Hello" is "Hello!" whereas foldl (flip (:)) "!" "Hello" is "olleH!" Nov 13 '12 at 21:38
• It's hard to see how can foldr even work with an infinite list as it seems the first application of function f is with z and the last item of the list. It will first need to traverse all the way to the last item which is infinite time in an infinite list. On the other hand foldl's first application of the function f is with z and the first item of the list. It can already start applying the function and we can traverse down the list lazily. Oct 27 '17 at 15:21
{"ft_lang_label":"__label__en","ft_lang_prob":0.8883927,"math_prob":0.9057748,"size":2965,"snap":"2022-05-2022-21","text_gpt3_token_len":840,"char_repetition_ratio":0.110773385,"word_repetition_ratio":0.027184466,"special_character_ratio":0.30623946,"punctuation_ratio":0.12903225,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.96749794,"pos_list":[0,1,2,3,4],"im_url_duplicate_count":[null,2,null,2,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-01-17T02:24:51Z\",\"WARC-Record-ID\":\"<urn:uuid:b2aa44f1-c48c-41aa-acbf-c4b8cbb8b1ee>\",\"Content-Length\":\"153932\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:2e460a1a-3db0-4c09-96d5-db4f6eb2fc67>\",\"WARC-Concurrent-To\":\"<urn:uuid:b2ccb920-3d9d-4d0f-9086-0feb10f23a88>\",\"WARC-IP-Address\":\"151.101.129.69\",\"WARC-Target-URI\":\"https://stackoverflow.com/questions/13280159/haskell-foldl-and-foldr/13280185\",\"WARC-Payload-Digest\":\"sha1:W2P6ZK4XRE65KNMCVT6WYTIUW4RH3QCW\",\"WARC-Block-Digest\":\"sha1:3LO2RXOCJBURD5SQYDAZ4TL6PWNWTPTT\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-05/CC-MAIN-2022-05_segments_1642320300253.51_warc_CC-MAIN-20220117000754-20220117030754-00275.warc.gz\"}"}