【发布时间】:2018-08-01 04:28:26
【问题描述】:
foldr 功能:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr func acc [] = acc
foldr func acc (x:xs) = func x (foldr func acc xs)
捕捉类似的模式(左侧) 并使它们更简单(右侧)
sum :: [Integer] -> Integer | sum :: [Integer] -> Integer
sum [] = 0 | sum [] = 0
sum (x:xs) = x + sum xs | sum (x:xs) = foldr (+) 0 xs
|
product :: [Integer] -> Integer | product :: [Integer] -> Integer
product [] = 0 | product [] = 0
product (x:xs) = x * product xs | product (x:xs) = foldr (*) 1 xs
|
concat :: [[a]] -> [a] | concat :: [[a]] -> [a]
concat [] = [] | concat [] = []
concat (x:xs) = x ++ concat xs | concat (x:xs) = foldr (++) [] xs
----------------------------------------------------------------------
not using folds | using folds
我注意到的一件事是 acc 参数作为折叠的输入提供, 似乎正是该功能的中性元素/身份元素。
In Mathematics the neutral element of the addition operation + is 0
because n + 0 = n, n ∈ ℝ
它不会改变任何东西,换句话说: 将此中性元素作为加法函数的输入提供后,被加数等于和。
(+) summand 0 = summand 或 summand + 0 = summand
乘法也是如此,因式和恒等式的乘积等于因式itelf:
(*) factor 1 = factor
所以这只是巧合还是背后有更大的原因?
【问题讨论】:
-
您的翻译表实际上是错误的。您不需要
[]与(x:xs)区分大小写,只需一个子句sum xs = foldr (+) 0 xs。 -
(另外,您使用了
foldl'而不是foldr,但这更多的是性能细节。) -
这不是巧合。你需要一些“中性”的初始元素来开始。但是没有什么能阻止你写 sumPlus5 = foldr 5
-
另外,
Product(即乘法的恒等参数)的mempty元素是1,而不是0。
标签: haskell