8

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.

4

2 回答 2

10

scanrfoldr什么scanl是什么foldlfoldr从右边开始工作:

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

scanr仅按顺序显示中间结果:[6,5,3,0]. 它可以定义为

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

scanl虽然应该像

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]

所以一定是这样

scanl (+) z xs = foldr f h xs z
   where h      z = [z]
         f x ys z = z : ys (z + x)
于 2013-07-30T14:08:50.237 回答
1

scanlscanr用于显示每次迭代时累加器的值。scanl从左到右和scanr从右到左迭代。

考虑以下示例:

scanl (+) 0 [1, 2, 3]

-- 0. `scanl` stores 0 as the accumulator and in the output list [0]
-- 1. `scanl` adds 0 and 1 and stores 1 as the accumulator and in the output list [0, 1]
-- 2. `scanl` adds 1 and 2 and stores 3 as the accumulator and in the output list [0, 1, 3]
-- 3. `scanl` adds 3 and 3 and stores 6 as the accumulator and in the output list [0, 1, 3, 6]
-- 4. `scanl` returns the output list [0, 1, 3, 6]

如您所见,scanl在迭代列表时存储累加器的结果。这对于 是相同的scanr,但列表是反向迭代的。

这是另一个例子:

scanl (flip (:)) [] [1, 2, 3]

-- [[], [1], [2,1], [3,2,1]]

scanr       (:)  [] [1, 2, 3]

-- [[1,2,3], [2,3], [3], []]
于 2021-01-31T17:24:31.210 回答