將列表減少為單個值
在 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]