Използване на Lambda.filter() в haxe въведени итерируеми или еквивалентна функционална конструкция

Как мога да накарам 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];

    }
}

Знам, че беше задаван преди, но отговорът даде алтернатива изпълнение, което мога да намеря сам, а не точен отговор за използването му. Намирам, че Lambda конструира основен компонент за функционално програмиране, особено по време на създаване на мързеливи композиции с помощта на map/reduce, и разбирам, че разбирането на списъка не ги замества.

Ако конструкциите Lambda наистина трябва да изчезнат и разбирането на списъци наистина е начинът да отидете в Haxe 3, защо модулът Lambda все още е там и как могат да бъдат използвани за постигане на мързел или неограничени нива на по-добра композиция?

Редактиране: Начин да го накарате да работи е да разширите итерируемия в масив, който със сигурност не е действително решение (циклете два пъти една и съща последователност!):

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

person Víctor R. Escobar    schedule 29.09.2015    source източник


Отговори (2)


Можете да опитате да кодирате мързелива версия на класа 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. В противен случай ще получите грешка „Не може да се създаде затваряне на вграден метод на абстрактен член“.

person Jonas Malaco    schedule 30.09.2015
comment
Здравейте, чудя се какъв е недостатъкът на lazylambda, изглежда ми доста добре. Защо функциите биха били по-добри? - person Mark Knol; 06.10.2015
comment
Може би не беше „глупаво“, просто не мисля, че нещо в посока на къси ламбда (дори ако по-късно винаги са били вградени) би било по-добре. Имаше някои подобрения в производителността, но поведението, което избрах, всъщност не реши проблема с многословието. Разбира се, ламбда извикванията станаха по-кратки, но чрез използването на фиксирани идентификатори (например $x) четливостта на потребителския код също намаля и използването до интерполации на низове стана наистина объркващо. Вземете това: в момента трябва да пиша vertices.map($x.x + ',' + $x.y ), вместо по-четливото vertices.map(v => '${v.x},{v,y}'). - person Jonas Malaco; 06.10.2015
comment
@MarkKnol, ще се радвам да чуя повече мисли по темата. Моля, не се колебайте да също отворите проблем или да се свържете с мен директно по имейл. - person Jonas Malaco; 06.10.2015

Проблемът е в разликата между Iterable и Iterator в Haxe, а Lambda не работи по подразбиране с Iterator (липсва му поддръжка, съобщава се в официалната общност помощна програма за проследяване на грешки от общността).

Темата може да се счита за дублирана: Lambda итерация върху итератор (не итерируем )

В текущото състояние помощните програми Lambda са просто остарели и не са достатъчно използваеми.

person Víctor R. Escobar    schedule 29.09.2015
comment
Настоящите Lambda помощни програми все още понякога са полезни, но да, липсват ни мързеливи техни версии, които работят предимно с итератори, вместо с итератори. Изграждането на нещо, което работи по този начин, е достатъчно лесно (може би дори с малко синтактична захар като кратки ламбда) и в крайна сметка дори може да влезе в стандартната библиотека някой ден. - person Jonas Malaco; 30.09.2015
comment
Да, прав сте, като казвате, че все още е полезен, но намирам, че не е валиден за всички възможни изходи от текущите методи за структура на данни на std библиотека, което го прави не общ надежден инструмент за всички случаи... Както казвате, новата библиотека трябва заеме своето място някъде в бъдещето, като донесе най-новите и най-добрите уроци, научени от други езици. - person Víctor R. Escobar; 30.09.2015