2014-09-03 39 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