Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I figured out how to fix the type error. The key to fixing type error is understanding the relationship between <strong><em>Data.ListLike.filter</em></strong> and <strong><em>ByteString</em></strong> input that is being passed to that filter. Here is the type of Data.ListLike.filter:</p> <pre><code>Data.ListLike.filter :: Data.ListLike.Base.ListLike full item =&gt; (item -&gt; Bool) -&gt; full -&gt; full </code></pre> <p><em><strong>full</em></strong> refers to the stream in the context of an enumerator/iteratee, if I understand it correctly. <strong><em>item</em></strong> refers to the element of the stream. </p> <p>Now, if we want to filter on newline in the input file, we have to know the type of input file stream, and the type of elements in that stream. In this case, input file is being read as <em>ByteString</em> stream. <em>ByteString</em> is documented as a space-efficient representation of a Word8 vector. So, <em>item</em> type here is Word8.</p> <p>So, when we write the filter, in the step function, we have to make sure that Bool operation is defined for Word8 since that is the type of the item being passed to the filter (as explained above). We are filtering for newline. So, the bool function like the one below which builds a Word8 representation of newline, and check for equality against x of type Word8, should work:</p> <pre><code>\x -&gt; x == Data.ByteString.Internal.c2w '\n' </code></pre> <p>There is still one more missing piece - for some reasons, the compiler (v7.0.3 Mac) is unable to deduce the type of <strong>el</strong> in numfile type signature (if anyone has ideas on why it is so, please do discuss). So, telling it explicitly that it is Word8 solves the compilation issue:</p> <pre><code>numlines :: (Monad m, Num a, LL.ListLike s Word8) =&gt; Iteratee s m a </code></pre> <p>Full code below - it compiles, and runs quite fast.</p> <pre><code>{-# LANGUAGE BangPatterns,FlexibleContexts #-} import Data.Iteratee as I import Data.ListLike as LL import Data.Iteratee.IO import Data.ByteString import GHC.Word (Word8) import Data.ByteString.Internal (c2w) numlines :: (Monad m, Num a, LL.ListLike s Word8) =&gt; Iteratee s m a numlines = liftI $ step 0 where step !i (Chunk xs) = let newline = c2w '\n' in liftI (step $i + fromIntegral (LL.length $ LL.filter (\x -&gt; x == newline) xs)) step !i stream = idone i stream {-# INLINE numlines #-} main = do i' &lt;- enumFile 1024 "/usr/share/dict/words" (numlines :: (Monad m) =&gt; Iteratee ByteString m Int) result &lt;- run i' print result {- Time to run on mac OSX: $ time ./test ## above compiled program: ghc --make -O2 test.hs 235886 real 0m0.011s user 0m0.007s sys 0m0.004s $ time wc -l /usr/share/dict/words 235886 /usr/share/dict/words real 0m0.005s user 0m0.002s sys 0m0.002s -} </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