Haskell 管道:如何对生产者的输出进行排序?

Haskell Pipes: How do I sort the output of a producer?

我有如下一段代码:

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中的所有文件。打印前如何对输出进行排序?我是否需要编写一个消费者,将 "drains" 输出首先放入列表中,然后对其进行排序?我正在使用 pipes-4.1.4.

是的,您需要先将输出排出,或者放入列表或其他结构中。排序本质上是非流式的,因为它可能是,例如,最后进来的元素应该最先出去。

toListM from Pipes.Prelude 将生产者转换为列表。我们可以使用它并在没有 pipes 的情况下继续:

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

或者使用通常的 monadic 运算符更像管道:

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

获取所有 Producer 内容将我们带到流抽象之外,这就是为什么 toListM returns 一个普通列表而不是一个管道。