2015-09-29 4 views
1

Как я могу заставить haxe Lambda.filter работать с типизированным итерабельным? Следующий код отказывается компилироваться из-за плохого типа:Использование Lambda.filter() в типизированных итерационных машинах haxe или эквивалентных функциональных конструкциях

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.filter([for (i in keys.keys()) i], function(k:Int) { return keys.exists(k); }); 

ответ

3

Вы можете попробовать написать ленивую версию класса Лямбда.

(Я сделал это в past, но я больше не использую его, поскольку он работал с выражениями и зарезервированными идентификаторами вместо функций/short lambdas, и теперь я думаю, что это было глупо).

В качестве альтернативы, вы можете использовать что-то вроде этого:

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/[email protected]. В противном случае вы получите ошибки «Невозможно создать замыкание на абстрактных элементах inline-метода».

+1

Привет, мне интересно, что такое нижняя сторона лазилямбды, это выглядит довольно хорошо для меня. Почему функции будут лучше? –

+0

Возможно, это было не «глупо», просто я не думаю, что что-то в сторону коротких лямбдов (даже если позже они всегда были в строю) было бы лучше.Были некоторые улучшения в производительности, но поведение, которое я выбрал, на самом деле не помогло решить проблему подробностей. Конечно, вызовы лямбда были короче, но с использованием фиксированных идентификаторов (например, '$ x') читаемость кода пользователя также уменьшилась, а использование рядом со строковыми интерполяциями стало действительно запутанным. Возьмем это: в настоящее время мне придется писать 'vertices.map ($ xx + ',' + $ xy)' вместо более читаемых 'vertices.map (v => '$ {vx}, {v, y} «)'. –

+1

@MarkKnol, я хотел бы услышать больше мыслей по этому вопросу. Пожалуйста, не стесняйтесь обращаться к нам или просто по электронной почте. –

2

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

Тема можно считать дублируется: Lambda iteration over an Iterator (not an Iterable)

В текущем состоянии утилиты Лямбда просто устарели и не достаточно использовать.

+0

Текущие утилиты Lambda по-прежнему иногда полезны, но да, у нас не хватает ленивых версий, которые работают в основном на итераторах, а не на Iterables. Построение чего-то, что работает так, достаточно просто (возможно, даже с некоторым синтаксическим сахаром, например, короткой лямбдой), и в конечном итоге может даже попасть в стандартную библиотеку когда-нибудь. –

+0

Да, вы правы, говоря, что это по-прежнему полезно, однако я считаю, что он недействителен для всех возможных выходов из существующих методов структуры данных std-библиотеки, что делает его не универсальным надежным инструментом для всех случаев ... Как вы говорите, новая библиотека должен занять свое место в будущем, принося последние и самые большие уроки, извлеченные из других языков. –