[英]How does scanr work? Haskell
我一直在使用一些 Haskell 函數,有些我理解,有些不理解。
例如,如果我們這樣做: scanl (+) 0 [1..3]
我的理解如下:
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
現在,當我們制作列表時,我們得到[0, 1, 3, 6]
。
但我似乎無法理解scanr (+) 0 [1..3]
給我: [6,5,3,0]
也許scanr
工作方式如下?
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...
我不知道這是不是模式。
scanr
是foldr
什么scanl
是foldl
。 foldr
從右邊開始工作:
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)
scanl
和scanr
用於顯示在每次迭代的累加器的值。 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], []]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.