1. 程式人生 > >Haskell --- flod函式中 flodl 和 flodr 與 foldl1 和 foldr1

Haskell --- flod函式中 flodl 和 flodr 與 foldl1 和 foldr1

一個fold取一個二元函式,一個初始值(我喜歡管它叫累加值)和一個需要fold(摺疊)的list。這個二元函式有兩個引數,即累加值和list的首項(或尾項),返回值是新的累加值。
然後,以新的累加值和新的list首項呼叫該函式,如是繼續。到list遍歷完畢時,只剩下一個累加值,也就是最終的結果。

foldl -- 也叫做左摺疊。它從list的左端開始摺疊,用初始值和list的頭部呼叫這二元函式,得一新的累加值,並用新的累加值與list的下一個元素呼叫二元函式。

foldr -- 右摺疊的行為與左摺疊相似,只是累加值是從list的右邊開始。

同樣,左摺疊的二元函式取累加值作首個引數,當前值為第二個引數(即\acc x -> ...),而右摺疊的二元函式引數的順序正好相反(即\x acc -> ...)。這倒也正常,畢竟是從右端開始摺疊。

累加值可以是任何型別,可以是數值,布林值,甚至一個新的list。我們可以用右fold實現map函式,累加值就是個list。將map處理過的元素一個一個連到一起。很容易想到,起始值就是空list。

 

foldl1與foldr1的行為與foldl和foldr相似,只是你無需明確提供初始值。他們假定list的首個(或末尾)元素作為起始值,並從旁邊的元素開始摺疊。
這一來,sum函式大可這樣實現:sum = foldl1 (+)。
這裡待摺疊的list中至少要有一個元素,若使用空list就會產生一個執行時錯誤。不過foldl和foldr與空list相處的就很好。
所以在使用fold前,應該先想下它會不會遇到空list,如果不會遇到,大可放心使用foldr1和foldl1。