Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you're using String IO, you can do the following:</p> <pre><code>import System.IO import Control.Monad -- | Process 100 lines process100 :: [String] -&gt; MyData -- whatever this function does loop :: [String] -&gt; [MyData] loop lns = go [] lns where go acc [] = reverse acc go acc lns = let (this, next) = splitAt 100 lns in go (process100 this:acc) next processFile :: FilePath -&gt; IO [MyData] processFile f = withFile f ReadMode (fmap (loop . lines) . hGetContents) </code></pre> <p>Note that this function will silently process the last chunk even if it isn't exactly 100 lines.</p> <p>Packages like bytestring and text generally provide functions like <code>lines</code> and <code>hGetContents</code> so you should be able to easily adapt this function to any of them.</p> <p>It's important to know what you're doing with the results of processing each slice, because you don't want to hold on to that data for longer than necessary. Ideally, after each slice is calculated the data would be entirely consumed and could be gc'd. Generally either the separate results get combined into a single data structure (a "fold"), or each one is dealt with separately (maybe outputting a line to a file or something similar). If it's a fold, you should change "loop" to look like this:</p> <pre><code>loopFold :: [String] -&gt; MyData -- assuming there is a Monoid instance for MyData loopFold lns = go mzero lns where go !acc [] = acc go !acc lns = let (this, next) = splitAt 100 lns in go (process100 this `mappend` acc) next </code></pre> <p>The <code>loopFold</code> function uses bang patterns (enabled with "LANGUAGE BangPatterns" pragma) to force evaluation of the "MyData". Depending on what MyData is, you may need to use <code>deepseq</code> to make sure it's fully evaluated.</p> <p>If instead you're writing each line to output, leave <code>loop</code> as it is and change <code>processFile</code>:</p> <pre><code>processFileMapping :: FilePath -&gt; IO () processFileMapping f = withFile f ReadMode pf where pf = mapM_ (putStrLn . show) &lt;=&lt; fmap (loop . lines) . hGetContents </code></pre> <p>If you're interested in enumerator/iteratee style processing, this is a pretty simple problem. I can't give a good example without knowing what sort of work <code>process100</code> is doing, but it would involve <code>enumLines</code> and <code>take</code>.</p> <p>Is it necessary to process exactly 100 lines at a time, or do you just want to process in chunks for efficiency? If it's the latter, don't worry about it. You'd most likely be better off processing one line at a time, using either an actual fold function or a function similar to processFileMapping.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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