How does scanr work? Haskell

fold, function, haskell, higher-order-functions, list

Solution

`scanr` is to `foldr` what `scanl` is to `foldl`. `foldr` works from the right:

foldr (+) 0 [1,2,3] =
  (1 + (2 + (3 +   0))) =
  (1 + (2 +    3)) =
  (1 +    5) =
     6
-- [ 6,   5,   3,   0 ]

and `scanr` just shows the interim results in sequence: `[6,5,3,0]`. It could be defined as

scanr (+) z xs = foldr g [z] xs
  where
  g x ys@(y:_) = x+y : ys

`scanl` though should work like

scanl (+) 0 [1,2,3] =
  0 : scanl (+) (0+1) [2,3] =
  0 : 1 : scanl (+) (1+2) [3] =
  0 : 1 : 3 : scanl (+) (3+3) [] =
  0 : 1 : 3 : [6]

so it must be that

scanl (+) z xs = foldr f h xs z
   where h      z = [z]
         f x ys z = z : ys (z + x)

Problem

I have been messing with some Haskell functions, some I have understand and some don't. For example if we do: `scanl (+) 0 [1..3]` my understanding is the following: ``` 1. the accumulator is 0 acc = 0 | 2. (+) applied to acc and first el acc = 0 + 1 = 1 | 3. (+) applied to latest acc and snd el acc = 1 + 2 = 3 | 4. (+) applied to latest acc and third acc = 3 + 3 = 6 V ``` Now when we make the list we get `[0, 1, 3, 6]`. But I can't seem to understand how does `scanr (+) 0 [1..3]` gives me: `[6,5,3,0]` Maybe `scanr` works the following way? ``` 1. the first element in the list is the sum of all other + acc 2. the second element is the sum from right to left (<-) of the last 2 elements 3. the third element is the sum of first 2... ``` I don't see if that's the pattern or not.

Original source