I have the following piece of code:
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
It prints all the files in the directory top
. How do I sort the output before I print it? Do I need to write a consumer that "drains" the output first into a list and then sorts it? I'm using pipes-4.1.4.
toListM
from Pipes.Prelude
converts a producer into a list. We can use that and proceed without pipes
afterwards:
runTest top = do
ds <- P.toListM (getDC top >-> P.map (top</>))
mapM_ print $ sort ds
Or a bit more pipe-like using usual monadic operators:
runTest top = P.toListM (getDC top >-> P.map (top</>)) >>= mapM_ print . sort
Grabbing all the Producer
contents brings us outside streaming abstraction, which is why toListM
returns a plain list instead of being a pipe.