f1 [] = 1
f1 (x:xs) = x * f1 xs
f2 [] = 0
f2 (x:xs) = 1 + f2 xs
f3 [] = 0
f3 (x:xs) = x + f3 xs
f4 [] = []
f4 (x:xs) = x ++ f4 xs
这些都有一个共同的行为,我该如何准确地识别模式并编写一个高阶函数来捕获它?
所有*您的函数具有以下形式:
fn [] = P_0
fn (x:xs) = P_1 x (fn xs)
其中P_0
和P_1
是一些常数。我将分别调用P_0
zero
和P_1
combine
,并将它们添加到函数中:
-- P_0 P_1 list = result
fn zero _ [] = zero
fn zero combine (x:xs) = combine x (fn zero combine xs)
好了 现在我们有f1 = fn 1 (*)
,f3 = fn 0 (+)
和f4 = fn [] (++)
。f2
是有点怪异,但你可以解决它:f2 = fn 0 (\_ b -> b+1)
。
向GHCi询问类型可以使我们知道fn :: b -> (a -> b -> b) -> [a] -> b
,而Hoogling向我们表明该函数fn
实际上是该函数foldr
:
foldr :: (a -> b -> b) -> b -> [a] -> b
-- ^combine ^zero
因此,您可以进行以下操作:折叠,或者特别是正确的折叠(r
infoldr
表示正确)是您要寻找的常规样式。
顺便说一句,也有左折。我将让您尝试解决这些问题。Hoogle也可以在这里为您提供帮助。
您可以在此处看到另一个模式,称为Monoids,但我也将其留给您,因为它似乎超出了此问题的范围。
*这可能看起来很奇怪f2 (x:xs) = 1 + f2 xs
,因为x
结果没有涉及,但这只是where的情况,在P_1 a b = 1 + b
技术上仍然是相同的形式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句