laker001
laker001

Reputation: 417

Replacing foldr with foldl

I have this function to sum the odd numbers on a list:

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

if i want to do it with foldl, how would it change?

Upvotes: 1

Views: 366

Answers (3)

karakfa
karakfa

Reputation: 67557

In general, you can implement foldr using foldl and vice versa. For example:

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

Upvotes: 0

bheklilr
bheklilr

Reputation: 54078

In your case it's very easy, you can just swap the order of the arguments to get it to work correctly:

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

This is primarily because your accumulator type is the same as your list element type, and because + is commutative and associative. This is important due to how foldl and foldr reduce a list:

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

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

In this case 1 + (3 + (5 + 0)) == ((0 + 1) + 3) + 5, but this isn't true of all operators, such as : or ++.

Upvotes: 4

Eugene Sh.
Eugene Sh.

Reputation: 18381

Just change the lambda's signature, since it should first take the accumulator and then the list element:

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

Allways use :t <function> if you are unsure how to use function

Upvotes: 1

Related Questions