将列表减少为单个值
在 Elm 中,缩减函数称为折叠,并且有两种标准方法可以向上折叠值:从左侧,foldl
,以及从右侧,foldr
。
> List.foldl (+) 0 [1,2,3]
6 : number
foldl
和 foldr
的论据是:
- 减少功能 :
newValue -> accumulator -> accumulator
- 累加器起始值
- 列表减少
自定义函数的另一个示例:
type alias Counts =
{ odd : Int
, even : Int
}
addCount : Int -> Counts -> Counts
addCount num counts =
let
(incOdd, incEven) =
if num `rem` 2 == 0
then (0,1)
else (1,0)
in
{ counts
| odd = counts.odd + incOdd
, even = counts.even + incEven
}
> List.foldl
addCount
{ odd = 0, even = 0 }
[1,2,3,4,5]
{ odd = 3, even = 2 } : Counts
在上面的第一个例子中,程序如下:
List.foldl (+) 0 [1,2,3]
3 + (2 + (1 + 0))
3 + (2 + 1)
3 + 3
6
List.foldr (+) 0 [1,2,3]
1 + (2 + (3 + 0))
1 + (2 + 3)
1 + 5
6
在像 (+)
这样的交换函数的情况下,并没有真正的区别。
但是看看 (::)
会发生什么:
List.foldl (::) [] [1,2,3]
3 :: (2 :: (1 :: []))
3 :: (2 :: [1])
3 :: [2,1]
[3,2,1]
List.foldr (::) [] [1,2,3]
1 :: (2 :: (3 :: []))
1 :: (2 :: [3])
1 :: [2,3]
[1,2,3]