Haskell Pipes: как сортировать вывод производителя?

У меня есть следующий фрагмент кода:

import Control.Monad (unless)
import Pipes
import qualified Pipes.Prelude as P
import System.FilePath.Posix ((</>))
import System.Posix.Directory (DirStream, openDirStream, readDirStream)

produceFiles :: DirStream -> Producer FilePath IO ()
produceFiles ds = do
  path <- lift $ readDirStream ds
  yield path
  unless (path == "") $ produceFiles ds

getDC :: FilePath -> Producer FilePath IO ()
getDC top = do
  ds <- lift $ openDirStream top
  produceFiles ds

runTest top = runEffect $ getDC top >-> P.map (top</>) >-> P.stdoutLn

Он печатает все файлы в каталоге top. Как сортировать вывод перед печатью? Нужно ли мне писать потребителя, который сначала «сливает» вывод в список, а затем сортирует его? Я использую трубы-4.1.4.


person Jan Synáček    schedule 20.03.2016    source источник


Ответы (2)


toListM from Pipes.Prelude преобразует производителя в список . Мы можем использовать это и продолжить без pipes впоследствии:

runTest top = do
  ds <- P.toListM (getDC top >-> P.map (top</>))
  mapM_ print $ sort ds

Или немного более похоже на трубу, используя обычные монадические операторы:

runTest top = P.toListM (getDC top >-> P.map (top</>)) >>= mapM_ print . sort

Захват всего содержимого Producer выводит нас за пределы потоковой абстракции, поэтому toListM возвращает простой список, а не канал.

person András Kovács    schedule 20.03.2016

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

person dfeuer    schedule 20.03.2016