Mathieu Bouchard <matju / CAM.ORG> writes:

> > M> Totally unrelated, I propose a new operation called "accum" in
> > M> Enumeration: 
> >  Something like apply (in scheme) ?
> 
> well, the first Scheme reference manual i found on the net (MIT's) says
> the "reduce" function is the actual equivalent: 
> 
> (reduce + 0 '(1 2 3 4))
> 10
> 
> (reduce * 0 '(1 2 3 4))
> 24

Although I'm sure this is lacking the subtleties of the Scheme
implementation, a naive Ruby version is trivial to hack together:


     def reduce(fn, res, *vals)
       vals.each { |v|
         res = res.send(fn, v)
       }
       res
     end

     p reduce(:*, 1, 2, 3, 4, 5)          # -> 120
     p reduce(:+, 'cat', 'dog', 'horse')  # -> catdoghorse
     p reduce(:|, 1, 16, 64)              # -> 81



Place the methods in the module Enumerable, and they automatically
work with all collections:


     module Enumerable
       def reduce(fn, res)
         each { |n| res = res.send(fn, n) }
         res
       end

       def reduceBlock(res)
         each { |n| res = yield(res, n) }
         res
       end

     end

     p [1,2,3,4,5,6].reduce(:*, 1)              # => 720
     p %w(cat dog horse).reduce(:+, '')         # => catdoghorse

     puts((1..5).reduceBlock(0) { |res, n| res + n })  # => 15
     p %w(cat dog horse).reduceBlock('Animals: ') { |res, n| res + n } 
                                                # => Animals: catdoghorse


I'm sure there are cleverer implementations.


Regards


Dave