Haskell’s foldr and foldl in… Ruby
- Published June 8th, 2007 in Ruby
I've found this very interesting snippet on how to implement the Haskell (and general FP methods) foldr() and foldl() in Ruby. Enjoy. It will spare you tons of confusing and error-prone lines dealing with Enumerable objects.
-
module Enumerable
-
def foldr(o, m = nil)
-
reverse.inject(m) {|m, i| m ? i.send(o, m) : i}
-
end
-
-
def foldl(o, m = nil)
-
inject(m) {|m, i| m ? m.send(o, i) : i}
-
end
-
end
-
-
[1, 2, 3, 4, 5].foldl(:+) #=> 15
-
[1, 2, 3, 4, 5].foldl(:*) #=> 120
-
-
[1, 2, 3, 4, 5].foldr(:-, 0) #=> 3
-
[1, 2, 3, 4, 5].foldl(:-, 0) #=> -15




import operator
a = [1,2,3,4,5]
sum(a) # 15
reduce(operator.mul, a) # 120
reduce(operator.sub, a) # 3
reduce(operator.sub, reversed(a)) # -15
BTW, I’m not trying to get into the Python vs. Ruby discussion here… Doesn’t Ruby have sum/reduce too?
I think this is clearer, and it’s faster too… ;)
Carlos,
Ruby does not have an explicit reduce or sum function, both easily implemented using inject().
As for being faster I honestly don’t know. Does Python have tail-call optimization? Otherwise those fold actions would be linear
Hmm it does not seem to have but there are ways around it
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474088
But Ruby doesn’t have tail-call optimization too.