I was doing the exercises from YAHT’s Recursive Datatype section, and found writing the listFoldr function a bit challenging (mainly because I didn’t really understand the difference between foldl and foldr at first). When I finally realized exactly how the foldr function worked, I decided that a simple swap of function arguments would be all that’d be needed to change my listFoldl function to a listFoldr function:
listFoldl f i [] = i
listFoldl f i (x:xs) = listFoldl f (f i x) xs
listFoldr f i [] = i
listFoldr f i (x:xs) = listFoldr f (f x i) xs
This appears to work (I did more tests than this):
Main> foldr (-) 4 [1, 2, 3]
-2
Main> listFoldr (-) 4 [1, 2, 3]
-2
But the solution given for the exercise is much different than mine. Their listFoldl is exactly the same as mine, but look at their listFoldr:
listFoldr f i [] = i
listFoldr f i (x:xs) = f x (listFoldr f i xs)
Which solution is better, mine or theirs? Is one of them incorrect? (In my tests, they both end up with the exact same result…)
I think you are processing the elements in the ‘opposite order’, and so yours is not right.
You should be able to demonstrate this with an example where ‘order matters’. For example, something like
where ‘f’ is a function along the lines of
where ‘@’ is a string-append operator (I forget what it is in Haskell). The point is just to ‘instrument’ the function so you can see what order it is getting called with the various args.
(Note that this didn’t show up in your example because the math “4-1-2-3” yields the same answer as “4-3-2-1”.)