Search code examples
rubyfunctional-programminglazy-evaluation

create a ruby enumerable from a first element, and a function to get the next element from the previous one


In Scala you can define a stream from its first element, and a function to get the next one from the previous one;

Stream.iterate(1)(x => 2 * x + 1)

Does something exist like this in Ruby?

Of course we can hand roll it-

 module Kernel
   def stream
     Enumerator.new do |y|
       that = self
       while true
         y << that
         that = yield that
       end
     end
   end
 end

But is it idiomatic? Is there something like this already?


Solution

  • What you are asking about is called an (which is called Stream.iterate in ), or more generically, an . It is the exact category-theoretical dual of a (which is called Enumerable#inject in ) aka a .

    Is there something like this already ?

    Unfortunately, there is no method in the core or standard library which performs this function.

    But is it idiomatic ?

    I would probably make it a singleton method of Enumerator and use Kernel#loop instead of while true, but that's about it. Otherwise, yes, your code is pretty idiomatic.

    And while we're at it, let's call it unfold:

    def Enumerator.unfold(start)
      new do |y|
        loop do
          y << start
          start = yield start
        end
      end
    end