5

I have the following code that should create a pipe Consumer for [Word8] and output it to a file.

import Pipes
import qualified Pipes.Binary as PB
import qualified Pipes.ByteString as PBS
import qualified System.IO as SIO 

save :: String -> Consumer [Word8] IO ()
save filename = do
  fh <- lift $ SIO.openFile filename WriteMode
  _ <- Pipes.for cat PB.encode >-> PBS.toHandle fh
  lift $ SIO.hClose fh

However, there is no output (although the file gets created). If I replace the "PBS.toHandle fh" with "PBS.stdout", I am getting the output (to stdout).

I also tried to use SIO.withFile with the whole pipeline I create as an argument, like

 SIO.withFile "output.bin" WriteMode $ \fh -> 
   runEffect $ input-processing >-> Pipes.for cat PB.encode >-> PBS.toHandle fh

and it works. But in that case, I am clueless as to how to put SIO.withFile into the function with the above signature (returning the consumer only).

Thank you for explanation about what I am doing wrong.

JS0
  • 173
  • 4
  • Using `withFile` seems like a good idea. pipes consumers don't wholly control when they stop running (the `Producer` might decide to stop by itself) and therefore make bad candidates for the responsibility of resource handling. – danidiaz Dec 11 '18 at 20:08
  • 1
    One option is to make use of the [`withFile`](https://hackage.haskell.org/package/pipes-safe-2.2.4/docs/Pipes-Safe-Prelude.html) in `Pipes.Safe.Prelude` – 4castle Dec 11 '18 at 20:17
  • Thanks. I decided to go with withFile on the outside for the moment. Although Pipes.Safe looks interesting - I wish it would be integrated into pipes, and the author also writes "I will release future separate packages with ByteString and Text operations", IMHO, that would be very useful too! – JS0 Dec 13 '18 at 10:39

0 Answers0