Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>ByteString isn't lazy so can't cope with the infinite answer from <code>cycleBytes</code>. (The <code>"</code> you're getting is because when printing the result, it can lazily get the first character of output without worrying about the rest, but then tries to calculate the infinite ByteString it gets from <code>cycleBytes</code> before printing anything else. Infinity and strict evaluation don't mix.)</p> <ol> <li>Import <code>Data.ByteString.Lazy</code> instead (and use <code>fromIntegral</code> on your <code>n</code>, because it wants <code>Int64</code> not <code>Int</code>; You might want to use Lazy ByteStrings for enormous amounts of data, so you the library needs a length parameter that allows this.) </li> <li>or (better) reduce <code>n</code> mod <code>B.length xs</code> and just use <code>B.append xs xs</code> instead of infinitely many.</li> </ol> <p>Solution 1 looks like </p> <pre><code>import qualified Data.ByteString.Lazy as B -- Cycle function for binary data cycleBytes :: B.ByteString -&gt; B.ByteString cycleBytes xs | B.null xs = error "cycleBytes: empty list" | otherwise = xs' where xs' = xs `B.append` xs' -- Rotate function for binary data rotateBytes :: B.ByteString -&gt; Int -&gt; B.ByteString rotateBytes xs n = B.take (B.length xs) $ B.drop (B.length xs + fromIntegral n) $ cycleBytes xs </code></pre> <p>If <code>test.dat</code> contained <code>Hello Mum!</code> this would calculate <code>Chunk "lo Mum!" (Chunk "Hel" Empty)</code>, because it's lazily constructed and will only get combined if it's forced.</p> <p>Solution 2 looks like</p> <pre><code>rotateBytes :: B.ByteString -&gt; Int -&gt; B.ByteString rotateBytes xs n = let len = B.length xs n' = n `mod` len in B.take len $! B.drop n' $! B.append xs xs </code></pre> <p>Solution 2 is better partly because you get to keep everything strict (which I assume you were trying to do), but doesn't have <code>cycleBytes</code>.</p> <p>Ben Millwood suggests replacing this with something along the lines of </p> <pre><code>rotateBytes :: B.ByteString -&gt; Int -&gt; B.ByteString rotateBytes xs n = let n' = n `mod` B.length xs (beginning,end) = B.splitAt n' xs in B.append end beginning </code></pre> <p>which reads more clearly. <code>take</code>, <code>drop</code> and <code>splitAt</code> are all <em>O(1)</em> in <code>ByteString</code>, so it doesn't make much difference for efficiency, but the <code>splitAt</code> does feel cleaner.</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.
 

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