2014-11-17 14 views
5

Ich denke, unendlich Enumerator ist sehr praktisch zum Schreiben von FP-Stil-Skripte, aber ich habe noch eine bequeme Möglichkeit, solche Struktur in Ruby zu konstruieren.Was ist die übliche schnelle Art, den unendlichen Enumerator `(1..Inf)` in Ruby auszudrücken?

Ich weiß, dass ich es ausdrücklich konstruieren kann:

a = Enumerator.new do |y| 
    i = 0 
    loop do 
     y << i += 1 
    end 
end 
a.next #=> 1 
a.next #=> 2 
a.next #=> 3 
... 

aber das ist annoyingly wortreich für eine solche einfache Struktur.

Ein anderer Ansatz ist eine Art „Hack“ Float::INFINITY verwenden:

b = (1..Float::INFINITY).each 
b = (1..1.0/0.0).each 

Diese beiden sind wahrscheinlich die am wenigsten ungeschickte Lösung, die ich geben kann. Obwohl ich gerne wissen würde, ob es eine andere elegantere Möglichkeit gibt, endlose Enumeratoren zu konstruieren. (Übrigens, warum macht Ruby nicht gerade inf oder infinity als Literal für Float::INFINITY?)

Antwort

2

Verwenden #to_enum oder #lazy Ihre Range zu einem Enumerable zu konvertieren. Zum Beispiel:

(1..Float::INFINITY).to_enum 
(1..Float::INFINITY).lazy 
+0

Danke. Ich wusste nicht über 'faul'. Scheint eine großartige Möglichkeit zu sein, FP-Prinzipien besser nachzuahmen. – trVoldemort

1

Ich würde persönlich meine eigene Ruby-Klasse dafür erstellen.

class NaturalNumbers 
    def self.each 
    i = 0 
    loop { yield i += 1 } 
    end 
end 

NaturalNumbers.each do |i| 
    puts i 
end 
+0

Was wäre, wenn ich 'def f (n) wollte; (1..1.0/0) .each_with_object ([]) {| i, a | a << i; return a wenn i * i == n}; Ende? Ich denke, Sie müssen einen Enumerator zurückgeben, wenn kein Block vorhanden ist. –