Is reduce() foldl() or foldr()?

  • Thread starter Steven D'Aprano
  • Start date
S

Steven D'Aprano

Calling all functional programming fans... is Python's built-in reduce()
a left-fold or a right-fold?

Wikipedia says it's a left-fold:

http://en.wikipedia.org/wiki/Fold_(higher-order_function)

but other people say it's a right-fold, e.g.:

"... there is a `foldr` in Haskell that just works like `reduce()`"
http://mail.python.org/pipermail/python-list/2007-November/638647.html


and

"Note that Python already has a variation of foldr, called reduce."
http://blog.sigfpe.com/2008/02/purely-functional-recursive-types-in.html


So which is correct? Or is it that different people have different
definitions of foldl() and foldr()?
 
P

Peter Otten

Steven said:
Calling all functional programming fans... is Python's built-in reduce()
a left-fold or a right-fold?

Wikipedia says it's a left-fold:

http://en.wikipedia.org/wiki/Fold_(higher-order_function)

Wikipedia is correct:
0.0083333333333333332

but other people say it's a right-fold, e.g.:

"... there is a `foldr` in Haskell that just works like `reduce()`"
http://mail.python.org/pipermail/python-list/2007-November/638647.html


and

"Note that Python already has a variation of foldr, called reduce."
http://blog.sigfpe.com/2008/02/purely-functional-recursive-types-in.html

The explicit foldr() function given in this blog agrees with Wikipedia's
definition:
.... if l == []:
.... return b
.... else:
.... return a(l[0], foldr(a, b, l[1:]))
....1.875

Peter
 
P

Paul Rubin

Steven D'Aprano said:
Calling all functional programming fans... is Python's built-in reduce()
a left-fold or a right-fold?

It's a left fold.
but other people say it's a right-fold, e.g.:
"... there is a `foldr` in Haskell that just works like `reduce()`"

That is correct in the sense that a coding situation where you'd use
reduce in Python would often lead you to use foldr (with its different
semantics) in Haskell. This is because of Haskell's lazy evaluation.
Example: suppose you have a list of lists, like xss =
[[1,2],[3,4,5],[6,7]] and you want to concatenate them all. (++) is
Haskell's list concatenation function, like Python uses + for list
concatenation. So you could say

ys = foldl (++) [] xss

but if I have it right, that would have to traverse the entire input
list before it gives you any of the answer, which can be expensive for
a long list, or fail totally for an infinite list. foldr on the other
hand can generate the result lazily, in sync with the way the caller
consumes the elements, like writing a generator in Haskell. The
tutorial

http://learnyouahaskell.com/higher-order-functions#folds

explains this a bit more. You might also like the Real World Haskell
book:

http://book.realworldhaskell.org
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,289
Messages
2,571,450
Members
48,127
Latest member
svastipharmancrr

Latest Threads

Top