packages feed

iteratee 0.8.7.6 → 0.8.8.0

raw patch · 7 files changed

+359/−81 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Iteratee.Binary: readWord16be_bs :: Monad m => Iteratee ByteString m Word16
+ Data.Iteratee.Binary: readWord16le_bs :: Monad m => Iteratee ByteString m Word16
+ Data.Iteratee.Binary: readWord32be_bs :: Monad m => Iteratee ByteString m Word32
+ Data.Iteratee.Binary: readWord32le_bs :: Monad m => Iteratee ByteString m Word32
+ Data.Iteratee.Binary: readWord64be_bs :: Monad m => Iteratee ByteString m Word64
+ Data.Iteratee.Binary: readWord64le_bs :: Monad m => Iteratee ByteString m Word64
+ Data.Iteratee.Exception: class (Typeable e, Show e) => Exception e
+ Data.Iteratee.Exception: fromException :: Exception e => SomeException -> Maybe e
+ Data.Iteratee.Exception: toException :: Exception e => e -> SomeException
+ Data.Iteratee.ListLike: countConsumed :: (Monad m, ListLike s el, Nullable s, Integral n) => Iteratee s m a -> Iteratee s m (a, n)
+ Data.Iteratee.ListLike: greedy :: (Monad m, Functor m, ListLike s el', Monoid a) => Iteratee s m a -> Iteratee s m a

Files

iteratee.cabal view
@@ -1,5 +1,5 @@ name:          iteratee-version:       0.8.7.6+version:       0.8.8.0 synopsis:      Iteratee-based I/O description:   The Iteratee monad provides strict, safe, and functional I/O. In addition
src/Data/Iteratee/Binary.hs view
@@ -14,61 +14,67 @@   ,endianRead3i   ,endianRead4   ,endianRead8+  -- ** bytestring specializations+  ,readWord16be_bs+  ,readWord16le_bs+  ,readWord32be_bs+  ,readWord32le_bs+  ,readWord64be_bs+  ,readWord64le_bs ) where  import Data.Iteratee.Base import qualified Data.Iteratee.ListLike as I import qualified Data.ListLike as LL+import qualified Data.ByteString as B+import qualified Data.ByteString.Unsafe as B import Data.Word import Data.Bits import Data.Int - -- ------------------------------------------------------------------------ -- Binary Random IO Iteratees  -- Iteratees to read unsigned integers written in Big- or Little-endian ways --- |Indicate endian-ness.+-- | Indicate endian-ness. data Endian = MSB -- ^ Most Significant Byte is first (big-endian)   | LSB           -- ^ Least Significan Byte is first (little-endian)   deriving (Eq, Ord, Show, Enum)  endianRead2-  :: (Nullable s, LL.ListLike s Word8, Monad m) =>-     Endian-     -> Iteratee s m Word16+  :: (Nullable s, LL.ListLike s Word8, Monad m)+  => Endian+  -> Iteratee s m Word16 endianRead2 e = do   c1 <- I.head   c2 <- I.head   case e of-    MSB -> return $ (fromIntegral c1 `shiftL` 8) .|. fromIntegral c2-    LSB -> return $ (fromIntegral c2 `shiftL` 8) .|. fromIntegral c1+    MSB -> return $ word16 c1 c2+    LSB -> return $ word16 c2 c1+{-# INLINE endianRead2 #-}  endianRead3-  :: (Nullable s, LL.ListLike s Word8, Monad m) =>-     Endian-     -> Iteratee s m Word32+  :: (Nullable s, LL.ListLike s Word8, Monad m)+  => Endian+  -> Iteratee s m Word32 endianRead3 e = do   c1 <- I.head   c2 <- I.head   c3 <- I.head   case e of-    MSB -> return $ (((fromIntegral c1-                        `shiftL` 8) .|. fromIntegral c2)-                        `shiftL` 8) .|. fromIntegral c3-    LSB -> return $ (((fromIntegral c3-                        `shiftL` 8) .|. fromIntegral c2)-                        `shiftL` 8) .|. fromIntegral c1+    MSB -> return $ word32 0 c1 c2 c3+    LSB -> return $ word32 0 c3 c2 c1+{-# INLINE endianRead3 #-}  -- |Read 3 bytes in an endian manner.  If the first bit is set (negative), -- set the entire first byte so the Int32 will be negative as -- well. endianRead3i-  :: (Nullable s, LL.ListLike s Word8, Monad m) =>-     Endian-     -> Iteratee s m Int32+  :: (Nullable s, LL.ListLike s Word8, Monad m)+  => Endian+  -> Iteratee s m Int32 endianRead3i e = do   c1 <- I.head   c2 <- I.head@@ -83,57 +89,227 @@      in return $ (((fromIntegral c3                         `shiftL` 8) .|. fromIntegral c2)                         `shiftL` 8) .|. fromIntegral m+{-# INLINE endianRead3i #-}  endianRead4-  :: (Nullable s, LL.ListLike s Word8, Monad m) =>-     Endian-     -> Iteratee s m Word32+  :: (Nullable s, LL.ListLike s Word8, Monad m)+  => Endian+  -> Iteratee s m Word32 endianRead4 e = do-  c1 <- I.head-  c2 <- I.head-  c3 <- I.head-  c4 <- I.head-  case e of-    MSB -> return $-               (((((fromIntegral c1-                `shiftL` 8) .|. fromIntegral c2)-                `shiftL` 8) .|. fromIntegral c3)-                `shiftL` 8) .|. fromIntegral c4-    LSB -> return $-               (((((fromIntegral c4-                `shiftL` 8) .|. fromIntegral c3)-                `shiftL` 8) .|. fromIntegral c2)-                `shiftL` 8) .|. fromIntegral c1+  ln' <- I.chunkLength+  case ln' of+    Just ln | ln >= 4 -> do+      ck <- I.getChunk+      let t = LL.drop 4 ck+          res = case e of+                  MSB -> word32 (LL.index ck 0)+                                (LL.index ck 1)+                                (LL.index ck 2)+                                (LL.index ck 3)+                  LSB -> word32 (LL.index ck 3)+                                (LL.index ck 2)+                                (LL.index ck 1)+                                (LL.index ck 0)+      res `seq` idone res (I.Chunk t)+    _ -> do+      c1 <- I.head+      c2 <- I.head+      c3 <- I.head+      c4 <- I.head+      return $ case e of+        MSB -> word32 c1 c2 c3 c4+        LSB -> word32 c4 c3 c2 c1+{-# INLINE [1] endianRead4 #-}  endianRead8-  :: (Nullable s, LL.ListLike s Word8, Monad m) =>-     Endian-     -> Iteratee s m Word64+  :: (Nullable s, LL.ListLike s Word8, Monad m)+  => Endian+  -> Iteratee s m Word64 endianRead8 e = do-  c1 <- I.head-  c2 <- I.head-  c3 <- I.head-  c4 <- I.head-  c5 <- I.head-  c6 <- I.head-  c7 <- I.head-  c8 <- I.head-  case e of-    MSB -> return $-               (((((((((((((fromIntegral c1-                `shiftL` 8) .|. fromIntegral c2)-                `shiftL` 8) .|. fromIntegral c3)-                `shiftL` 8) .|. fromIntegral c4)-                `shiftL` 8) .|. fromIntegral c5)-                `shiftL` 8) .|. fromIntegral c6)-                `shiftL` 8) .|. fromIntegral c7)-                `shiftL` 8) .|. fromIntegral c8-    LSB -> return $-               (((((((((((((fromIntegral c8-                `shiftL` 8) .|. fromIntegral c7)-                `shiftL` 8) .|. fromIntegral c6)-                `shiftL` 8) .|. fromIntegral c5)-                `shiftL` 8) .|. fromIntegral c4)-                `shiftL` 8) .|. fromIntegral c3)-                `shiftL` 8) .|. fromIntegral c2)-                `shiftL` 8) .|. fromIntegral c1+  ln' <- I.chunkLength+  case ln' of+    Just ln | ln >= 8 -> do+      ck <- I.getChunk+      let t = LL.drop 8 ck+          res = case e of+                  MSB -> word64 (LL.index ck 0)+                                (LL.index ck 1)+                                (LL.index ck 2)+                                (LL.index ck 3)+                                (LL.index ck 4)+                                (LL.index ck 5)+                                (LL.index ck 6)+                                (LL.index ck 7)+                  LSB -> word64 (LL.index ck 7)+                                (LL.index ck 6)+                                (LL.index ck 5)+                                (LL.index ck 4)+                                (LL.index ck 3)+                                (LL.index ck 2)+                                (LL.index ck 1)+                                (LL.index ck 0)+      res `seq` idone res (I.Chunk t)+    _ -> do+      c1 <- I.head+      c2 <- I.head+      c3 <- I.head+      c4 <- I.head+      c5 <- I.head+      c6 <- I.head+      c7 <- I.head+      c8 <- I.head+      return $ case e of+        MSB -> word64 c1 c2 c3 c4 c5 c6 c7 c8+        LSB -> word64 c8 c7 c6 c5 c4 c3 c2 c1+{-# INLINE [1] endianRead8 #-}++{-# RULES "iteratee: binary bytestring spec." endianRead4 = endianRead4BS #-}+{-# RULES "iteratee: binary bytestring spec." endianRead8 = endianRead8BS #-}++endianRead4BS :: Monad m => Endian -> Iteratee B.ByteString m Word32+endianRead4BS MSB = readWord32be_bs+endianRead4BS LSB = readWord32le_bs+{-# INLINE endianRead4BS  #-}++endianRead8BS :: Monad m => Endian -> Iteratee B.ByteString m Word64+endianRead8BS MSB = readWord64be_bs+endianRead8BS LSB = readWord64le_bs+{-# INLINE endianRead8BS  #-}++-- the 16-bit variant is only included for completeness; the+-- polymorphic code is as fast as any specialization I've yet found+-- in these cases.  (JWL, 2012-01-09)+readWord16be_bs :: Monad m => Iteratee B.ByteString m Word16+readWord16be_bs = endianRead2 MSB+{-# INLINE readWord16be_bs  #-}++readWord16le_bs :: Monad m => Iteratee B.ByteString m Word16+readWord16le_bs = endianRead2 LSB+{-# INLINE readWord16le_bs  #-}++readWord32be_bs :: Monad m => Iteratee B.ByteString m Word32+readWord32be_bs = do+  ln' <- I.chunkLength+  case ln' of+    Just ln | ln >= 4 -> do+      ck <- I.getChunk+      let t = B.drop 4 ck+          res = word32 (B.unsafeIndex ck 0)+                       (B.unsafeIndex ck 1)+                       (B.unsafeIndex ck 2)+                       (B.unsafeIndex ck 3)+      res `seq` idone res (I.Chunk t)+    _ -> do+      c1 <- I.head+      c2 <- I.head+      c3 <- I.head+      c4 <- I.head+      return $! word32 c1 c2 c3 c4+{-# INLINE readWord32be_bs  #-}++readWord32le_bs :: Monad m => Iteratee B.ByteString m Word32+readWord32le_bs = do+  ln' <- I.chunkLength+  case ln' of+    Just ln | ln >= 4 -> do+      ck <- I.getChunk+      let t = B.drop 4 ck+          res = word32 (B.unsafeIndex ck 3)+                       (B.unsafeIndex ck 2)+                       (B.unsafeIndex ck 1)+                       (B.unsafeIndex ck 0)+      res `seq` idone res (I.Chunk t)+    _ -> do+      c1 <- I.head+      c2 <- I.head+      c3 <- I.head+      c4 <- I.head+      return $! word32 c4 c3 c2 c1+{-# INLINE readWord32le_bs  #-}++readWord64be_bs :: Monad m => Iteratee B.ByteString m Word64+readWord64be_bs = do+  ln' <- I.chunkLength+  case ln' of+    Just ln | ln >= 8 -> do+      ck <- I.getChunk+      let t = B.drop 8 ck+          res = word64 (B.unsafeIndex ck 0)+                       (B.unsafeIndex ck 1)+                       (B.unsafeIndex ck 2)+                       (B.unsafeIndex ck 3)+                       (B.unsafeIndex ck 4)+                       (B.unsafeIndex ck 5)+                       (B.unsafeIndex ck 6)+                       (B.unsafeIndex ck 7)+      res `seq` idone res (I.Chunk t)+    _ -> do+      cs <- I.joinI $ I.take 8 I.stream2stream+      if B.length cs == 8+        then return $ word64 (B.unsafeIndex cs 0)+                             (B.unsafeIndex cs 1)+                             (B.unsafeIndex cs 2)+                             (B.unsafeIndex cs 3)+                             (B.unsafeIndex cs 4)+                             (B.unsafeIndex cs 5)+                             (B.unsafeIndex cs 6)+                             (B.unsafeIndex cs 7)+        else I.throwErr (toException EofException)+{-# INLINE readWord64be_bs  #-}++readWord64le_bs :: Monad m => Iteratee B.ByteString m Word64+readWord64le_bs = do+  ln' <- I.chunkLength+  case ln' of+    Just ln | ln >= 8 -> do+      ck <- I.getChunk+      let t = B.drop 8 ck+          res = word64 (B.unsafeIndex ck 7)+                       (B.unsafeIndex ck 6)+                       (B.unsafeIndex ck 5)+                       (B.unsafeIndex ck 4)+                       (B.unsafeIndex ck 3)+                       (B.unsafeIndex ck 2)+                       (B.unsafeIndex ck 1)+                       (B.unsafeIndex ck 0)+      res `seq` idone res (I.Chunk t)+    _ -> do+      cs <- I.joinI $ I.take 8 I.stream2stream+      if B.length cs == 8+        then return $ word64 (B.unsafeIndex cs 7)+                             (B.unsafeIndex cs 6)+                             (B.unsafeIndex cs 5)+                             (B.unsafeIndex cs 4)+                             (B.unsafeIndex cs 3)+                             (B.unsafeIndex cs 2)+                             (B.unsafeIndex cs 1)+                             (B.unsafeIndex cs 0)+        else I.throwErr (toException EofException)+{-# INLINE readWord64le_bs  #-}++word16 :: Word8 -> Word8 -> Word16+word16 c1 c2 = (fromIntegral c1 `shiftL`  8) .|.  fromIntegral c2+{-# INLINE word16 #-}++word32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32+word32 c1 c2 c3 c4 =+  (fromIntegral c1 `shiftL` 24) .|.+  (fromIntegral c2 `shiftL` 16) .|.+  (fromIntegral c3 `shiftL`  8) .|.+   fromIntegral c4+{-# INLINE word32 #-}++word64+  :: Word8 -> Word8 -> Word8 -> Word8 +  -> Word8 -> Word8 -> Word8 -> Word8 +  -> Word64+word64 c1 c2 c3 c4 c5 c6 c7 c8 =+  (fromIntegral c1 `shiftL` 56) .|.+  (fromIntegral c2 `shiftL` 48) .|.+  (fromIntegral c3 `shiftL` 40) .|.+  (fromIntegral c4 `shiftL` 32) .|.+  (fromIntegral c5 `shiftL` 24) .|.+  (fromIntegral c6 `shiftL` 16) .|.+  (fromIntegral c7 `shiftL`  8) .|.+   fromIntegral c8+{-# INLINE word64 #-}
src/Data/Iteratee/Exception.hs view
@@ -40,6 +40,7 @@ module Data.Iteratee.Exception (   -- * Exception types   IFException (..)+  ,Exception (..)             -- from Control.Exception   -- ** Enumerator exceptions   ,EnumException (..)   ,DivergentException (..)
src/Data/Iteratee/Iteratee.hs view
@@ -245,6 +245,7 @@       onCont k Nothing  = runIter (f k Nothing) od oc       onCont k (Just e) = runIter (h k e)       od oc   in runIter inner onDone onCont+{-# INLINABLE eneeCheckIfDoneHandle #-}  eneeCheckIfDonePass   :: (Monad m, NullPoint elo)@@ -254,7 +255,7 @@      )   -> Enumeratee elo eli m a eneeCheckIfDonePass f = eneeCheckIfDoneHandle (\k e -> f k (Just e)) f-{-# INLINEABLE eneeCheckIfDonePass #-}+{-# INLINABLE eneeCheckIfDonePass #-}  eneeCheckIfDoneIgnore   :: (Monad m, NullPoint elo)@@ -292,6 +293,7 @@ {-# INLINE mapChunksM #-}  -- |Convert one stream into another, not necessarily in lockstep.+--  -- The transformer mapStream maps one element of the outer stream -- to one element of the nested stream.  The transformer below is more -- general: it may take several elements of the outer stream to produce@@ -307,6 +309,7 @@     check k (Just e) = throwRecoverableErr e (const identity) >> check k Nothing     check k _ = isStreamFinished >>= maybe (step k) (idone (liftI k) . EOF . Just)     step k = fi >>= eneeCheckIfDonePass check . k . Chunk+{-# INLINABLE convStream #-}  -- |The most general stream converter.  Given a function to produce iteratee -- transformers and an initial state, convert the stream using iteratees@@ -345,6 +348,7 @@       let i = f acc >>= \(acc', s') ->                            (checkDone (check acc') . k $ Chunk s')       in joinIM $ enumChunk str' i+{-# INLINABLE unfoldConvStreamCheck #-}  -- | Collapse a nested iteratee.  The inner iteratee is terminated by @EOF@. --   Errors are propagated through the result.@@ -373,7 +377,8 @@  -- ------------------------------------------------------------------------ -- Enumerators--- |Each enumerator takes an iteratee and returns an iteratee+-- | Each enumerator takes an iteratee and returns an iteratee+--  -- an Enumerator is an iteratee transformer. -- The enumerator normally stops when the stream is terminated -- or when the iteratee moves to the done state, whichever comes first.@@ -414,6 +419,7 @@   -- |The composition of two enumerators: essentially the functional composition+--  -- It is convenient to flip the order of the arguments of the composition -- though: in e1 >>> e2, e1 is executed first 
src/Data/Iteratee/ListLike.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleContexts, BangPatterns, TupleSections #-}+{-# LANGUAGE FlexibleContexts, BangPatterns, TupleSections, ScopedTypeVariables #-}  -- |Monadic Iteratees: -- incremental input parsers, processors and transformers@@ -58,6 +58,8 @@   ,zip4   ,zip5   ,sequence_+  ,countConsumed+  ,greedy   -- ** Monadic functions   ,mapM_   ,foldM@@ -80,7 +82,6 @@ import Control.Monad.Trans.Class import Data.Word (Word8) import qualified Data.ByteString as B-import qualified Data.ByteString.Char8 as BC  -- Useful combinators for implementing iteratees and enumerators @@ -354,9 +355,7 @@       | otherwise          = idone (k (Chunk s1)) (Chunk s2)       where (s1, s2) = LL.splitAt n str     step _n k stream       = idone (k stream) stream-{-# SPECIALIZE take :: Monad m => Int -> Enumeratee [el] [el] m a #-}-{-# SPECIALIZE take :: Monad m => Int -> Enumeratee B.ByteString B.ByteString m a #-}-{-# SPECIALIZE take :: Monad m => Int -> Enumeratee BC.ByteString BC.ByteString m a #-}+{-# INLINE take #-}  -- |Read n elements from a stream and apply the given iteratee to the -- stream of the read elements. If the given iteratee accepted fewer@@ -410,9 +409,7 @@                 Left  (a,s')       -> od' (idone a s') (Chunk s2)                 Right (k',e)       -> od' (icont k' e) (Chunk s2)     step _ k stream       = idone (k stream) stream-{-# SPECIALIZE takeUpTo :: Monad m => Int -> Enumeratee [el] [el] m a #-}-{-# SPECIALIZE takeUpTo :: Monad m => Int -> Enumeratee B.ByteString B.ByteString m a #-}-{-# INLINABLE takeUpTo #-}+{-# INLINE takeUpTo #-}  -- | Takes an element predicate and returns the (possibly empty) -- prefix of the stream. All characters@@ -963,6 +960,28 @@     shorter e@(EOF _) _         = e     shorter _         e@(EOF _) = e +-- |Transform an iteratee into one that keeps track of how much data it+-- consumes.+countConsumed :: forall a s el m n.+                 (Monad m, LL.ListLike s el, Nullable s, Integral n) =>+                 Iteratee s m a+              -> Iteratee s m (a, n)+countConsumed i = go 0 (const i) (Chunk empty)+  where+    go :: n -> (Stream s -> Iteratee s m a) -> Stream s+       -> Iteratee s m (a, n)+    go !n f str@(EOF _) = (, n) `liftM` f str+    go !n f str@(Chunk c) = Iteratee rI+      where+        newLen = n + fromIntegral (LL.length c)+        rI od oc = runIter (f str) onDone onCont+          where+            onDone a str'@(Chunk c') =+                od (a, newLen - fromIntegral (LL.length c')) str'+            onDone a str'@(EOF _) = od (a, n) str'+            onCont f' mExc = oc (go newLen f') mExc+{-# INLINE countConsumed #-}+ -- ------------------------------------------------------------------------ -- Enumerators @@ -982,6 +1001,49 @@                        in runIter iter' idoneM on_cont {-# INLINE enumPureNChunk #-} +-- | Convert an iteratee to a \"greedy\" version.+--+-- When a chunk is received, repeatedly run the input iteratee+-- until the entire chunk is consumed, then the outputs+-- are combined (via 'mconcat').+--+-- > > let l = [1..5::Int]+-- > > run =<< enumPure1Chunk l (joinI (take 2 stream2list))+-- > [1,2]+-- > > run =<< enumPure1Chunk l (greedy $ joinI (I.take 2 stream2list))+-- > [1,2,3,4,5]+--+-- Note that a greedy iteratee will consume the entire input chunk and force+-- the next chunk before returning a value.  A portion of the second chunk may+-- be consumed.+-- +-- 'greedy' may be useful on the first parameter of 'convStream', e.g.+-- +-- > convStream (greedy someIter)+--+-- to create more efficient converters.+greedy ::+ (Monad m, Functor m, LL.ListLike s el', Monoid a) =>+  Iteratee s m a+  -> Iteratee s m a+greedy iter' = liftI (step [] iter')+ where+  step acc iter (Chunk str)+    | LL.null str = liftI (step acc iter)+    | otherwise   = joinIM $ do+      i2 <- enumPure1Chunk str iter+      result <- runIter i2 (\a s -> return $ Left (a,s))+                           (\k e -> return $ Right (icont k e))+      case result of+        Left (a, Chunk resS)+          | LL.null resS+              || LL.length resS == LL.length str -> return $+                         idone (mconcat $ reverse (a:acc)) (Chunk resS)+        Left (a, stream) -> return $ step (a:acc) iter stream+        Right i -> return $ fmap (mconcat . reverse . (:acc)) i+  step acc iter stream = joinIM $+    enumChunk stream (fmap (mconcat . reverse . (:acc)) iter)+{-# INLINE greedy #-}  -- ------------------------------------------------------------------------ -- Monadic functions
tests/benchmarks.hs view
@@ -7,6 +7,7 @@ import Data.Iteratee import qualified Data.Iteratee.ListLike as I import qualified Data.Iteratee.Parallel as I+import qualified Data.Iteratee.Binary as I import Data.Iteratee.ListLike (enumPureNChunk, stream2list, stream2stream) import Data.Word import Data.Monoid@@ -35,6 +36,7 @@  id1  name i = BDIter1 name id i idN  name i = BDIterN name 5 id i+idNx name sz i = BDIterN name sz id i idNl name i = BDIterN name 1000 id i  defTotalSize = 10000@@ -78,6 +80,7 @@ headsbench = makeGroup "heads" headsBenches dropbench = makeGroup "drop" $ drop0 : dropBenches zipbench = makeGroup "zip" $ zipBenches+consbench = makeGroup "consumed" consBenches lengthbench = makeGroup "length" listBenches takebench = makeGroup "take" $ take0 : takeBenches takeUpTobench = makeGroup "takeUpTo" takeUpToBenches@@ -93,6 +96,7 @@ headsbenchbs = makeGroupBS "heads" headsBenches dropbenchbs = makeGroupBS "drop" dropBenches zipbenchbs = makeGroupBS "zip" zipBenches+consbenchbs = makeGroupBS "consumed" consBenches lengthbenchbs = makeGroupBS "length" listBenches takebenchbs = makeGroupBS "take" takeBenches takeUpTobenchbs = makeGroupBS "takeUpTo" takeUpToBenches@@ -102,11 +106,17 @@ convbenchbs = makeGroupBS "convStream" convBenches miscbenchbs = makeGroupBS "other" miscBenches +endian2benchbs = makeGroupBS "2" endian2Benches+endian3benchbs = makeGroupBS "3" endian3Benches+endian4benchbs = makeGroupBS "4" endian4Benches+endian8benchbs = makeGroupBS "8" endian8Benches+endianbenchbs = bgroup "endian" [endian2benchbs, endian3benchbs, endian4benchbs, endian8benchbs] -allListBenches = bgroup "list" [listbench, streambench, breakbench, headsbench, dropbench, zipbench, lengthbench, takebench, takeUpTobench, groupbench, mapbench, foldbench, convbench, miscbench] -allByteStringBenches = bgroup "bytestring" [listbenchbs, streambenchbs, breakbenchbs, headsbenchbs, dropbenchbs, zipbenchbs, lengthbenchbs, takebenchbs, takeUpTobenchbs, groupbenchbs, mapbenchbs, foldbenchbs, convbenchbs, miscbenchbs]+allListBenches = bgroup "list" [listbench, streambench, breakbench, headsbench, dropbench, zipbench, lengthbench, takebench, takeUpTobench, groupbench, mapbench, foldbench, convbench, miscbench, consbench] +allByteStringBenches = bgroup "bytestring" [listbenchbs, streambenchbs, breakbenchbs, headsbenchbs, dropbenchbs, zipbenchbs, lengthbenchbs, takebenchbs, takeUpTobenchbs, groupbenchbs, mapbenchbs, foldbenchbs, convbenchbs, endianbenchbs, miscbenchbs, consbenchbs]+ list0 = makeList "list one go" deepseq list1 = BDIter1 "stream2list one go" (flip deepseq ()) stream2list list2 = BDIterN "stream2list chunk by 4" 4 (flip deepseq ()) stream2list@@ -158,7 +168,11 @@ b_zip4 = idN "zip nonterminating" (I.zip I.length I.stream2stream >> identity) zipBenches = [b_zip0, b_zip1, b_zip2, b_zip3, b_zip4 ] +consumed0 = idN "countConsumed" (I.countConsumed (I.foldl' (+) 0))+consumed1 = idN "countConsumed baseline (`I.enumWith` I.length)" (I.foldl' (+) 0 `I.enumWith` I.length)+consBenches = [consumed0, consumed1] + l1 = makeList "length of list" Prelude.length l2 = id1 "length single iteratee" I.length l3 = idN "length chunked" I.length@@ -209,3 +223,17 @@  instance NFData a => NFData (Sum a) where   rnf (Sum a) = rnf a++endianRead2_1 = id1 "endianRead2 single" (I.endianRead2 MSB)+endianRead2_2 = idNx "endianRead2 chunked" 1 (I.endianRead2 MSB)+endianRead3_1 = id1 "endianRead3 single" (I.endianRead3 MSB)+endianRead3_2 = idNx "endianRead3 chunked" 2 (I.endianRead3 MSB)+endianRead4_1 = id1 "endianRead4 single" (I.endianRead4 MSB)+endianRead4_2 = idNx "endianRead4 chunked" 2 (I.endianRead4 MSB)+endianRead8_1 = id1 "endianRead8 single" (I.endianRead8 MSB)+endianRead8_2 = idN "endianRead8 chunked" (I.endianRead8 MSB)+endianRead8_3 = idNx "endianRead8 multiple chunked" 2 (I.endianRead8 MSB)+endian2Benches = [endianRead2_1, endianRead2_2]+endian3Benches = [endianRead3_1, endianRead3_2]+endian4Benches = [endianRead4_1, endianRead4_2]+endian8Benches = [endianRead8_1, endianRead8_2, endianRead8_3]
tests/testIteratee.hs view
@@ -1,5 +1,5 @@ {-# OPTIONS_GHC -O #-}-{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE NoMonomorphismRestriction, ViewPatterns #-}  import Prelude as P @@ -242,6 +242,10 @@    ==  runner1 (enumSpecial xs n (i >> stream2list))  where types = (xs :: [Int], i :: I) +prop_countConsumed (Positive (min (2^10) -> n)) (Positive (min (2^20) -> a)) (Positive k) =+            runner1 (enumPureNChunk [1..] n iter) == (a, a)+  where+    iter = countConsumed . joinI $ (takeUpTo (a + k) ><> Iter.take a) Iter.last  -- --------------------------------------------- -- Nested Iteratees@@ -515,6 +519,7 @@     testProperty "enumWith" prop_enumWith     ,testProperty "enumWith remaining" prop_enumWith2     ,testProperty "enumWith remaining 2" prop_enumWith3+    ,testProperty "countConsumed" prop_countConsumed     ]   ,testGroup "Folds" [     testProperty "foldl" prop_foldl