Как бы вы собираете результаты списка Async a
в Haskell как они становятся доступными? Идея состоит в том, чтобы начать обработку результатов асинхронных задач, как только они будут доступны.Сбор результатов ASync как они становятся доступными
Лучшее, что я мог придумать следующая функция:
collect :: [Async a] -> IO [a]
collect [] = return []
collect asyncs = do
(a, r) <- waitAny asyncs
rs <- collect (filter (/= a) asyncs)
return (r:rs)
Однако эта функция не проявляет желаемое поведение, поскольку, как было указано в комментарии ниже, не возвращается, пока все асинхронные задачи завершены. Кроме того, collect
работает в O(n^2)
, так как я фильтрую список на каждом рекурсивном шаге. Это может быть улучшено за счет использования более эффективной структуры (и, возможно, индексации позиции значений Async
в списке).
Возможно, есть функции библиотеки, которые позаботились об этом, но я не смог найти их в модуле Control.Concurrent.Async
, и мне интересно, почему.
EDIT: после того, как немного более тщательно думать проблему, я задаюсь вопросом, такая функция является ли хорошей идеей. Я мог бы просто использовать fmap
для асинхронных задач. Может быть, лучше подождать результатов, когда нет другого выбора.
Ваш 'collect' не возвращается, пока все' Async 'в списке не будут выполнены. Это то, что вам нужно? –
Нет. Я этого не осознавал. Моя реализация действительно ошибается. Моя идея заключалась в том, что «collect» возвращает результат, как только асинхронный поток будет готов. Я отредактирую свой ответ соответственно. –