There are several equivalent ways to figure this out. First: foldr fz [1, 2, 3, 4, ..., n] calculates the following value:
f 1 (f 2 (f 3 (f 4 (f ... (fnz)))))
So in your case:
length [1,2,3,4] = foldr (\_ n -> 1 + n) 0 [1,2,3,4] = (\_ n -> 1 + n) 1 ((\_ n -> 1 + n) 2 ((\_ n -> 1 + n) 3 ((\_ n -> 1 + n) 4 0))) = (\_ n -> 1 + n) 1 ((\_ n -> 1 + n) 2 ((\_ n -> 1 + n) 3 (1 + 0))) = (\_ n -> 1 + n) 1 ((\_ n -> 1 + n) 2 (1 + (1 + 0))) = (\_ n -> 1 + n) 1 (1 + (1 + (1 + 0))) = 1 + (1 + (1 + (1 + 0))) = 1 + (1 + (1 + 1)) = 1 + (1 + 2) = 1 + 3 = 4
Another task is to start with this function, which copies the list:
listCopy :: [a] -> [a] listCopy [] = [] listCopy (x:xs) = x : listCopy xs
It may look like a trivial function, but foldr is basically such that, in addition to hard coding an empty list [] and a pair constructor : on the right side, instead we use some arbitrary constant and a function provided as arguments. I sometimes like to call these arguments fakeCons and fakeNil ( cons and nil are the names of the operator : and constants [] in Lisp), because in a sense, re "copy" the list, but using fake constructors:
foldr fakeCons fakeNil [] = fakeNil foldr fakeCons fakeNil (x:xs) = fakeCons x (subfold xs) where subfold = foldr fakeCons fakeNil
So, with this interpretation, your length function βcopiesβ the list, except that instead of using an empty list, it uses 0 , and instead : it discards the elements and adds 1 to the total.
And here's the third foldr fz xs intuition:
z is the solution to your problem when the list is empty.f is a function that takes two arguments: a list item and a partial solution : a solution to your problem for a list of items that appear to the right of the item that went to f . f then creates a solution that is "one element more."
So in the case of length :
- The length of the empty list is 0, so why are you using 0 as the second argument to
foldr . - If the length
xs is n , then the length x:xs is n+1 . This is what your first argument to foldr , \_ n -> n + 1 does: it computes the length of the list given as arguments by the first element of the list (which we ignore in this case) and the length of the rest of the list ( n ).
This foldr way of thinking is very powerful and should not be underestimated. Basically, in the function that you pass as the first argument to foldr , you can assume that the problem you are trying to solve is already solved for all lists shorter than the one you are dealing with. Thus, your entire argument function should calculate the answer for a list that is one item longer.