1

我有以下代码:

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。

4

2 回答 2

4

toListMfromPipes.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返回一个普通列表而不是管道的原因。

于 2016-03-20T17:16:12.743 回答
1

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

于 2016-03-20T17:15:33.717 回答