I often read it's impossible to call Lambda functions on iterators. And I lived in that belief until now. However reading the book Professional Haxe by Franco Ponticelli and Lee-McColl-Sylvester about what makes an objet an Iterable or an Iterator made me think of one trick, that seems to work; at least in the simple case I just tested.
The trick is simply to declare an iterator() function inside the Iterator class, returning itself (weird yes, but not that incoherent).
I don't know if this will work in the general case, but this simple examples compiles and works fine on both Haxe 2 and Haxe 3 (http://try.haxe.org/#b764F):
using Lambda;
class IntIter2 {
var min : Int;
var max : Int;
public inline function new( min : Int, max : Int ) {
this.min = min;
this.max = max;
}
public inline function hasNext() { return min < max; }
public inline function next() { return min++; }
// here goes the magic/weirdness/abomination
public function iterator():IntIter2 { return this; }
}
class Test {
public static function main() {
var evenNumbers = new IntIter2(3, 10)
.filter( function (n:Int):Bool return n % 2 == 0 )
.list() // unneeded, in fact...
;
trace(evenNumbers.toString());
// list even numbers in the series, ie {4, 6, 8}
}
}
Why it works (at least here)
"In the haXe standard library, two very commonly used typedefs are defined: Iterator and Iterable.
Their definition is as follows:
typedef Iterator<T> = {
function hasNext() : Bool;
function next() : T;
}
typedef Iterable<T> = {
function iterator() : Iterator<T>;
}
" - Haxe Professional by Franco Ponticelli and Lee-McColl-Sylvester
Therefore adding iterator() to an Iterator class makes it Iterable, and usable with Lambda functions. Or is that always so simple?