# This imagines `.unfold` to be an alternate constructor for `Enumerator` that's
# more complex than `.produce` but not as custom as the full `.new`. It follows the rules
# of anamorphisms (at least for arrays, not sure if this genericises to other structures)
class CustomEnumerator
  def self.unfold(seed, &block)
    Enumerator.new do |yielder|
      loop do
        seed, value = block.call(seed)
        raise StopIteration if value.nil?

        yielder << value
      end
    end
  end
end

CustomEnumerator.unfold(1) { |seed| [seed + 1, seed * seed] }.take(10)
#=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]