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.
2 ответа
toListM
от 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
возвращает простой список, а не трубу.
Да, вам нужно сначала слить вывод, либо в список нашей какой-то другой структуры. Сортировка по своей сути не является потоковой, потому что, например, последний входящий элемент должен быть первым выходящим.