Lambda.filter() 在 haxe 类型的可迭代对象或等效函数构造中的使用

Usage of Lambda.filter() in haxe typed iterables or equivalent functional construct

如何让 haxe Lambda.filter 与类型化的可迭代对象一起工作?由于类型错误,下一个代码拒绝编译:

Iterator<Int> should be Iterable<Unknown<0>> { next : Void -> Int, hasNext : Void -> Bool } should be Iterable<Unknown<0>>

代码示例:

import Lambda;
import openfl.events.KeyboardEvent;

class KeyBoard {
    private var keys:Map<Int,Bool>;
    public function new() keys = new Map();
    public function key_handler(key:KeyboardEvent) {
        if (key.type == KeyboardEvent.KEY_DOWN) keys.set(key.keyCode, true);
        if (key.type == KeyboardEvent.KEY_UP) keys.remove(key.keyCode);
    }
    public function keys_down() {
        return Lambda.filter(keys.keys(), function(k:Int) { return keys.exists(k);});
        // The comprehension working alternative:
        //return [for (k in keys.keys()) if (keys.exists(k)) k];

    }
}

我知道它 has been asked before 但答案给出了我可以自己找到的替代实现,而不是关于其用法的准确答案。我发现 Lambda 为函数式编程构建了一个基本组件,尤其是在使用 map/reduce 创建惰性组合时,我知道列表推导不会取代它们。

如果 Lambda 结构真的必须消失,而列表推导确实是 Haxe 3 中的必经之路,为什么 Lambda 模块仍然存在,如何使用它们来实现惰性或无限级别的更好组合?

编辑:使其工作的一种方法是将可迭代对象扩展为一个数组,这肯定不是实际的解决方案(循环两次相同的序列!):

Lambda.filter([for (i in keys.keys()) i], function(k:Int) { return keys.exists(k); });

问题是 Haxe 中的 Iterable 和 Iterator 之间的区别,Lambda 默认情况下不能与 Iterator 一起工作(它缺乏支持,据官方社区报道 bug tracking 实用程序来自社区).

主题可能被认为是重复的: Lambda iteration over an Iterator (not an Iterable)

在目前的状态下,Lambda 实用程序只是过时的,没有足够的可用性。

您可以尝试编写 Lambda 的惰性版本 class。

(我在 past 中做到了,但我不再使用它,因为它使用表达式和保留标识符而不是 functions/short lambda,我现在认为那是愚蠢)。

或者,您可以使用这样的东西:

using Test.IteratorTools;

class IteratorTools {
    public static function toIterable<T>(f:Void->Iterator<T>):Iterable<T>
    {
        return {
            iterator : f
        };
    }
}

class Test {
    static function main() {
        var map = ["a" => "abc", "b" => "bcd", "c" => "cde"];
        var fkeys = Lambda.filter(map.keys.toIterable(), function(k) return k != "c");
        trace(fkeys);
    }
}

请注意,要使其正常工作,您需要 haxe 的开发版本,至少需要提交 HaxeFoundation/haxe@f6cd97b。否则,您将得到 "Cannot create closure on abstract member inline method" 个错误。