用foldl替换foldr

时间:2015-02-02 19:30:33

标签: haskell

我有这个函数来对列表中的奇数求和:

idOdd xs = foldr (\x acc -> if odd x then x+acc else acc) 0 xs

如果我想用foldl做,它会如何改变?

3 个答案:

答案 0 :(得分:4)

在您的情况下,它非常简单,您只需交换参数的顺序即可使其正常工作:

idOdd2 = foldl (\acc x -> if odd x then x + acc else acc) 0

这主要是因为您的累加器类型与列表元素类型相同,并且因为+是可交换和关联的。这很重要,因为foldlfoldr减少了一个列表:

isOdd [1, 2, 3, 4, 5] = 1 + (3 + (5 + 0)) = 9

isOdd2 [1, 2, 3, 4, 5] = ((0 + 1) + 3) + 5 = 9

在这种情况下1 + (3 + (5 + 0)) == ((0 + 1) + 3) + 5,但所有运营商都不是这样,例如:++

答案 1 :(得分:1)

只需更改lambda的签名,因为它应首先使用累加器,然后是list元素:

idOdd2 xs = foldl  (\acc x -> if odd x then x+acc else acc) 0 xs

如果您不确定如何使用:t <function>

,请始终使用function

答案 2 :(得分:0)

通常,您可以使用foldl实现foldr,反之亦然。例如:

foldr' f e xs = foldl (flip f) e (reverse xs)