`streamN` just replicates the`streamN` in pipes-http, which presupposes that 
the underlying monad for the byte stream is IO. But `Q.writeFile file` gives 
you a stream with the underlying monad `ResourceT IO`.

It should be possible to write a `streamN` that takes a `ByteString 
(ResourceT IO) ()`, though. See the duplication of functions in 
`http-conduit`

    - IO :                     
 
http://hackage.haskell.org/package/http-conduit-2.1.10.1/docs/Network-HTTP-Client-Conduit.html#v:requestBodySource
 
 
    - ResourceT IO :   
http://hackage.haskell.org/package/http-conduit-2.1.10.1/docs/Network-HTTP-Client-Conduit.html#v:requestBodySource
 
 

The first takes a `Source IO ByteString`, the second a `Source (ResourceT 
IO) ByteString`. `streamN` here, replicating pipes-http, is like the first 
of these.

It's always possible I'm missing something in the `ResourceT` + `Conduit` 
wilderness of mirrors, but we just need an equivalent of `to` from 
Pipes.HTTP that is more like something like `srcToPopper` inside 
Network.HTTP.Conduit.  

    streamN' :: Int64 -> Q.ByteString (ResourceT IO) () -> SP.RequestBody
    streamN' n str =  SP.RequestBodyStream n (popperize str)

    -- cp the helper functions `Pipes.HTTP.to` and 
`Network.HTTP.srcToPopper`
    popperize ::  Q.ByteString (ResourceT IO) () -> (IO ByteString -> IO a) 
-> IO a
    popperize str0 with_reader = runResourceT $ do
      ref <- liftIO (newIORef str0)
      is  <- getInternalState
      let reader :: IO ByteString
          reader = do
              str <- readIORef ref
              e   <- runInternalState (Q.nextChunk str) is  -- Q.nextChunk 
str is in ResourceT IO but we 
              case e of                                     -- here purport 
to run it safely in IO
                Left r -> do 
                  writeIORef ref (return r)
                  return mempty     -- the apparatus will take this null 
chunk as eof, so ...
                Right (chunk, rsrc') -> do
                    writeIORef ref rsrc'
                    if B.null chunk  -- ... here we have to make sure not 
to return one.
                      then reader
                      else return chunk
      liftIO (with_reader reader) 



I haven't tested this with anything real, but it works with this trivial 
`NeedsPopper`

    -- lengthy :: SP.NeedsPopper Int
    lengthy :: IO ByteString -> IO Int
    lengthy act = loop 0 
      where
        loop n = do 
          chunk <- act
          let len = B.length chunk
          if len > 0 
            then loop (n+len)
            else return n
 
    -- >>> popperize (Q.readFile "/usr/share/dict/words") lengthy
    -- 2493109

    -- >>> runResourceT $ Q.length  (Q.readFile "/usr/share/dict/words")
    -- 2493109 :> ()

    -- >>> :! wc -c /usr/share/dict/words
    --  2493109 /usr/share/dict/words


 It would be interesting to know if it can survive the aws machinery.

-- 
You received this message because you are subscribed to the Google Groups 
"Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to haskell-pipes+unsubscr...@googlegroups.com.
To post to this group, send email to haskell-pipes@googlegroups.com.

Reply via email to