2014-09-03 68 views
2

我經常讀到,在迭代器上調用Lambda函數是不可能的。直到現在,我仍然堅信這種信念。然而,閱讀由Franco Ponticelli和Lee-McColl-Sylvester撰寫的專業Haxe關於什麼使得Iterable或迭代器成爲可能或者迭代器的原因讓我想到了一個技巧,這看起來似乎有效;至少在我剛測試的簡單情況下。Iterator上的Lambda迭代(不是可迭代的)

訣竅很簡單,就是聲明一個迭代()函數的迭代器類,返回本身(奇怪的是,但不是語無倫次)。

我不知道這是否會在一般情況下工作,但這個簡單的例子編譯和兩個HAXE 2和3 HAXE工作正常(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} 
    } 
} 

爲什麼它的工作原理(至少在這裏)

「在haXe的標準庫,兩個非常常用的typedef定義:迭代器和可迭代

它們的定義如下:

typedef Iterator<T> = { 
    function hasNext() : Bool; 
    function next() : T; 
} 
typedef Iterable<T> = { 
    function iterator() : Iterator<T>; 
} 

「 - HAXE專業佛朗哥Ponticelli和Lee-麥科爾-西爾威斯特

因此增加迭代器()到一個Iterator類使得它可迭代,可使用的與lambda函數。還是那麼簡單?

+0

**編輯**:我的測試表明,它甚至更復雜的情況(模板化的迭代類在模板類繼承他人等)的作品。只要確保編寫'function iterator():NameOfTheClass {}'而不是'function iterator():Iterator {}',你會沒事的(否則在第二種情況下它會抱怨迭代器沒有'Lambda。過濾器「或其他任何你嘗試使用的同態方法)。 – 2014-09-03 19:40:58

回答

2

退房的HAXE庫本(開放)的問題:

Lambda should support Iterator as well as Iterable #1914

在線程的最後評論實際上是你所建議 - 它可以工作,但改變的定義「迭代器「,以便每個迭代器本身」迭代「是一個突破性變化,在Haxe 3期間不可能發生變化。也許對於Haxe 4 :)

另一種選擇是使用允許隱式轉換的摘要來創建Iterable類型的Iter類型:

abstract Iter<T>(Iterator<T>) from Iterator<T> to Iterator<T> { 
    inline function new(it:Iterator<T>) 
    this = it; 

    @:from static public inline function fromIterable(it:Iterable<T>) { 
    return new Iter(it.iterator()); 
    } 
} 

我在該問題的評論中寫道一下:https://github.com/HaxeFoundation/haxe/issues/1914#issuecomment-19380450

你可以使用Iter項目來創建自己的自定義拉姆達幫手既可迭代和迭代器的工作原理。

祝你好運:)

+0

我跟着你的鏈接,這是一個偉大的討論去那裏。但是我真的不明白用'abstract'解決你的問題,'從Iterator 到Iterator '。我想這是Haxe 3中的新東西。我不知道這是否會在轉換階段造成問題,但如果沒有,我認爲所有迭代器都應該是可重用的。用Java這樣的語言來分離這兩個概念是有道理的,但是對於一種稱爲Haxe的語言(「hacks」)來說,堅持迭代器的正統概念只是限制,所以我也會在Haxe中提倡它4. – 2014-09-04 10:13:12

+0

順便說一下,如果它們都是可迭代的,那它真的會是一個突破性的改變嗎?無可否認,它會徹底改變迭代器的概念,所以不要做它,但我不會馬上看到它會如何破壞事物(也許我沒有足夠的想象力)。 – 2014-09-04 10:25:04

+0

唯一會中斷的是如果你有自定義迭代器。因此,如果我現在有一個類與可重用的匹配的類,但是接下來可重用的更改爲需要迭代器():Iterable 函數,我的自定義迭代器不再是迭代器。我不親自在我的代碼中使用自定義迭代器,但我相信有些人會這樣做......除此之外,它不會真的破壞任何東西:) – 2014-09-04 14:03:10