Note that there are some explanatory texts on larger screens.

plurals
  1. POHaskell Lazy ByteString + read/write progress function
    text
    copied!<p>I am learing Haskell Lazy IO.</p> <p>I am looking for an elegant way to copy a large file (8Gb) while printing copy progress to console.</p> <p>Consider the following simple program that copies a file silently.</p> <pre><code>module Main where import System import qualified Data.ByteString.Lazy as B main = do [from, to] &lt;- getArgs body &lt;- B.readFile from B.writeFile to body </code></pre> <p>Imgine there is a callback function you want to use for reporting:</p> <pre><code>onReadBytes :: Integer -&gt; IO () onReadBytes count = putStrLn $ "Bytes read: " ++ (show count) </code></pre> <p><strong>QUESTION:</strong> how to weave onReadBytes function into Lazy ByteString so it will be called back on successfull read? Or if this design is not good, then what is the Haskell way to do it?</p> <p><strong>NOTE:</strong> the frequency of callback is not important, it can be called every 1024 bytes or every 1 Mb -- not important</p> <p><strong>ANSWER:</strong> Many thanks to camccann for the answer. I suggest to read it entirely.</p> <p>Bellow is my version of the code based on camccann's code, you may find it useful.</p> <pre><code>module Main where import System import System.IO import qualified Data.ByteString.Lazy as B main = do [from, to] &lt;- getArgs withFile from ReadMode $ \fromH -&gt; withFile to WriteMode $ \toH -&gt; copyH fromH toH $ \x -&gt; putStrLn $ "Bytes copied: " ++ show x copyH :: Handle -&gt; Handle -&gt; (Integer -&gt; IO()) -&gt; IO () copyH fromH toH onProgress = copy (B.hGet fromH (256 * 1024)) (write toH) B.null onProgress where write o x = do B.hPut o x return . fromIntegral $ B.length x copy :: (Monad m) =&gt; m a -&gt; (a -&gt; m Integer) -&gt; (a -&gt; Bool) -&gt; (Integer -&gt; m()) -&gt; m() copy = copy_ 0 copy_ :: (Monad m) =&gt; Integer -&gt; m a -&gt; (a -&gt; m Integer) -&gt; (a -&gt; Bool) -&gt; (Integer -&gt; m()) -&gt; m() copy_ count inp outp done onProgress = do x &lt;- inp unless (done x) $ do n &lt;- outp x onProgress (n + count) copy_ (n + count) inp outp done onProgress </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload