Как сгенерировать несколько Enumerators из одного Enumerator (раздел, разделение, ..)

Можно ли создать несколько Enumerators из одного Enumerator ? Я ищу эквивалент List.partition, который возвращает (List[A], List[A]) , например

List().partition(_.age >= 18) 

Поэтому в идеале я хотел бы применить преобразование к перечислителю, которое позволит мне разделить данные, чтобы получить пару (Enumerator[T], Enumerator[T]).

Легко ли это сделать с помощью Play Iteratee API?

Самое близкое, что я нашел, это метод Enumeratee.grouped, который позволяет группировать входные данные, но, насколько я понимаю, если все, что я хочу, это 2 раздела (группы), мне придется использовать все Enumerator, чтобы получить результат. Но я бы хотел, чтобы результирующие Enumerators подавались асинхронно из ввода.


person Sami Dalouche    schedule 03.12.2013    source источник


Ответы (1)


В отличие от List, Enumerator представляет собой не набор данных, а скорее источник данных, к которому может быть подключен Iteratee. Данные передаются в Iteratee по мере того, как Iteratee потребляет ввод. Из-за этого не совсем ясно, как будут вести себя два экземпляра Enumerator, возвращаемые этим Enumerator.partition. Если Iteratee, потребляющее первое Enumerator, готово к большему вводу, а второе нет, что произойдет? Нужно ли ждать первого? Буферизируются ли данные для второго? Что произойдет, если один из двух экземпляров Iteratee скажет, что ему больше не нужны данные, или умрет с ошибкой? Мы убьем другого? Позволим этому продолжаться, отбросив данные, изначально предназначенные для мертвых Iteratee?

Из-за этого не может быть единого канонического метода partition, как для List. Вы, конечно, можете написать один, который ведет себя так, как вы хотите, но на практике может быть проще, чтобы один Iteratee выполнял всю обработку. Если вы ищете partition, потому что хотите запустить два потока параллельно, вы, вероятно, захотите использовать Akka. Если вы просто хотите иметь конвейерный параллелизм, который предоставляет API Iteratee, вы можете иметь Enumeratee[Whatever, Either[Whatever]], который позволит более поздним экземплярам Enumeratee преобразовывать только ту часть потока, которая им нужна.

Если вы готовы заниматься черной магией преобразования монад, то я думаю, что может быть способ использовать что-то вроде Haskell EitherT. Но не делай этого.

person wingedsubmariner    schedule 04.12.2013