Left and Right Folding over an Infinite list

前端 未结 5 1521
北荒
北荒 2020-12-07 14:03

I have issues with the following passage from Learn You A Haskell (Great book imo, not dissing it):

One big difference is that right folds work on i

5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-07 15:02

    The key phrase is "at some point".

    if you take an infinite list at some point and you fold it up from the right, you'll eventually reach the beginning of the list.

    So you're right, you can't possibly start at the "last" element of an infinite list. But the author's point is this: suppose you could. Just pick a point waaay far out there (for engineers, this is "close enough" to infinity) and start folding leftwards. Eventually you end up at the start of the list. The same is not true of the left fold, if you pick a point waaaay out there (and call it "close enough" to the start of the list), and start folding rightwards, you still have an infinite way to go.

    So the trick is, sometimes you don't need to go to infinity. You may not need to even go waaaay out there. But you may not know how far out you need to go beforehand, in which case infinite lists are quite handy.

    The simple illustration is foldr (:) [] [1..]. Let's perform the fold.

    Recall that foldr f z (x:xs) = f x (foldr f z xs). On an infinite list, it actually doesn't matter what z is so I'm just keeping it as z instead of [] which clutters the illustration

    foldr (:) z (1:[2..])         ==> (:) 1 (foldr (:) z [2..])
    1 : foldr (:) z (2:[3..])     ==> 1 : (:) 2 (foldr (:) z [3..])
    1 : 2 : foldr (:) z (3:[4..]) ==> 1 : 2 : (:) 3 (foldr (:) z [4..])
    1 : 2 : 3 : ( lazily evaluated thunk - foldr (:) z [4..] )
    

    See how foldr, despite theoretically being a fold from the right, in this case actually cranks out individual elements of the resultant list starting at the left? So if you take 3 from this list, you can clearly see that it will be able to produce [1,2,3] and need not evaluate the fold any farther.

提交回复
热议问题