packages feed

iteratee 0.8.0.3 → 0.8.1.0

raw patch · 9 files changed

+126/−15 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Iteratee.Char: printLinesUnterminated :: (Eq el, Nullable s, StringLike s, ListLike s el) => Iteratee s IO ()
+ Data.Iteratee.Iteratee: mapChunksM_ :: (Monad m, Nullable s) => (s -> m b) -> Iteratee s m ()
+ Data.Iteratee.ListLike: breakE :: (Monad m, ListLike s el, NullPoint s) => (el -> Bool) -> Enumeratee s s m a

Files

iteratee.cabal view
@@ -1,5 +1,5 @@ name:          iteratee-version:       0.8.0.3+version:       0.8.1.0 synopsis:      Iteratee-based I/O description:   The Iteratee monad provides strict, safe, and functional I/O. In addition@@ -9,8 +9,8 @@ maintainer:    John W. Lato <jwlato@gmail.com> license:       BSD3 license-file:  LICENSE-homepage:      http://inmachina.net/~jwlato/haskell/iteratee-tested-with:   GHC == 6.12.3+homepage:      http://www.tiresiaspress.us/haskell/iteratee+tested-with:   GHC == 7.0.1, GHC == 6.12.3 stability:     experimental  cabal-version: >= 1.6@@ -111,4 +111,4 @@  source-repository head   type:     darcs-  location: http://inmachina.net/~jwlato/haskell/iteratee+  location: http://www.tiresiaspress.us/haskell/iteratee
src/Data/Iteratee/Base/ReadableChunk.hs view
@@ -13,6 +13,7 @@ import Prelude hiding (head, tail, dropWhile, length, splitAt )  import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L import Data.Word import Control.Monad.IO.Class import Foreign.C@@ -45,3 +46,7 @@  instance ReadableChunk B.ByteString Word8 where   readFromPtr buf l = liftIO $ B.packCStringLen (castPtr buf, l)++instance ReadableChunk L.ByteString Word8 where+  readFromPtr buf l = liftIO $+    return . L.fromChunks . (:[]) =<< readFromPtr buf l
src/Data/Iteratee/Char.hs view
@@ -1,10 +1,11 @@-{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}  -- | Utilities for Char-based iteratee processing.  module Data.Iteratee.Char (   -- * Word and Line processors   printLines+  ,printLinesUnterminated   ,enumLines   ,enumLinesBS   ,enumWords@@ -26,14 +27,42 @@  -- |Print lines as they are received. This is the first `impure' iteratee -- with non-trivial actions during chunk processing+--+--  Only lines ending with a newline are printed,+--  data terminated with EOF is not printed. printLines :: Iteratee String IO () printLines = lines'-  where+ where   lines' = I.break (`elem` "\r\n") >>= \l -> terminators >>= check l   check _  0 = return ()   check "" _ = return ()   check l  _ = liftIO (putStrLn l) >> lines'-  terminators = heads "\r\n" >>= \l -> if l == 0 then heads "\n" else return l++-- |Print lines as they are received.+--+--  All lines are printed, including a line with a terminating EOF.+--  If the final line is terminated by EOF without a newline,+--  no newline is printed.+--  this function should be used in preference to printLines when possible,+--  as it is more efficient with long lines.+printLinesUnterminated :: forall s el.+                       (Eq el, Nullable s, LL.StringLike s, LL.ListLike s el)+                       => Iteratee s IO ()+printLinesUnterminated = lines'+ where+  lines' = do+    joinI $ I.breakE (`LL.elem` t1) (I.mapChunksM_ (putStr . LL.toString))+    terminators >>= check+  check 0 = return ()+  check _ = liftIO (putStrLn "") >> lines'+  t1 :: s+  t1 = LL.fromString "\r\n"++terminators :: (Eq el, Nullable s, LL.StringLike s, LL.ListLike s el)+            => Iteratee s IO Int+terminators = do+  l <- heads (LL.fromString "\r\n")+  if l == 0 then heads (LL.fromString "\n") else return l   -- |Convert the stream of characters to the stream of lines, and
src/Data/Iteratee/Iteratee.hs view
@@ -13,6 +13,8 @@   ,identity   ,skipToEof   ,isStreamFinished+  -- ** Chunkwise Iteratees+  ,mapChunksM_   -- ** Nested iteratee combinators   ,convStream   ,unfoldConvStream@@ -46,6 +48,7 @@ import Data.Iteratee.Base  import Control.Exception+import Control.Monad.Trans.Class import Data.Maybe import Data.Typeable @@ -117,7 +120,21 @@ seek :: (Monad m, NullPoint s) => FileOffset -> Iteratee s m () seek o = throwRecoverableErr (toException $ SeekException o) (const identity) +-- | Map a monadic function over the chunks of the stream and ignore the+-- result.  Useful for creating efficient monadic iteratee consumers, e.g.+--+--   logger = mapChunksM_ (liftIO . putStrLn)+--+-- these can be efficiently run in parallel with other iteratees via+-- enumPair.+mapChunksM_ :: (Monad m, Nullable s) => (s -> m b) -> Iteratee s m ()+mapChunksM_ f = liftI step+  where+    step (Chunk xs) = lift (f xs) >> liftI step+    step s@(EOF _)  = idone () s+{-# INLINE mapChunksM_ #-} + -- --------------------------------------------------- -- The converters show a different way of composing two iteratees: -- `vertical' rather than `horizontal'@@ -146,7 +163,7 @@ -- general: it may take several elements of the outer stream to produce -- one element of the inner stream, or the other way around. -- The transformation from one stream to the other is specified as--- Iteratee s el s'.+-- Iteratee s m s'. convStream ::  (Monad m, Nullable s) =>   Iteratee s m s'@@ -154,7 +171,7 @@ convStream fi = eneeCheckIfDone check   where     check k = isStreamFinished >>= maybe (step k) (idone (liftI k) . EOF . Just)-    step k = fi >>= convStream fi . k . Chunk+    step k = fi >>= eneeCheckIfDone check . k . Chunk  -- |The most general stream converter.  Given a function to produce iteratee -- transformers and an initial state, convert the stream using iteratees
src/Data/Iteratee/ListLike.hs view
@@ -24,6 +24,7 @@   ,roll   ,length   -- ** Nested iteratee combinators+  ,breakE   ,take   ,takeUpTo   ,mapStream@@ -112,6 +113,10 @@ -- If the stream is not terminated, the first character of the remaining stream -- satisfies the predicate. --+-- N.B. @breakE@ should be used in preference to @break@.+-- @break@ will retain all data until the predicate is met, which may+-- result in a space leak.+-- -- The analogue of @List.break@  break :: (Monad m, LL.ListLike s el) => (el -> Bool) -> Iteratee s m s@@ -166,7 +171,7 @@   where   loop cnt xs     | nullC xs = return cnt-    | True    = liftI (step cnt xs)+    | True     = liftI (step cnt xs)   step cnt str (Chunk xs) | nullC xs  = liftI (step cnt str)   step cnt str stream     | nullC str = idone cnt stream   step cnt str s@(Chunk xs) =@@ -248,8 +253,8 @@ length :: (Monad m, Num a, LL.ListLike s el) => Iteratee s m a length = liftI (step 0)   where-    step !i (Chunk xs) = liftI (step $ i + LL.length xs)-    step !i stream     = idone (fromIntegral i) stream+    step !i (Chunk xs) = liftI (step $! i + fromIntegral (LL.length xs))+    step !i stream     = idone i stream {-# INLINE length #-}  @@ -257,6 +262,25 @@ -- The converters show a different way of composing two iteratees: -- `vertical' rather than `horizontal' +-- |Takes an element predicate and an iteratee, running the iteratee+-- on all elements of the stream until the predicate is met.+--+-- the following rule relates @break@ to @breakE@+-- @break@ pred >> iter === @joinI@ (@breakE@ pred iter)+--+-- @breakE@ should be used in preference to @break@ whenever possible.+breakE :: (Monad m, LL.ListLike s el, NullPoint s) => (el -> Bool) -> Enumeratee s s m a+breakE cpred = eneeCheckIfDone (liftI . step)+ where+  step k (Chunk s)+      | LL.null s  = liftI (step k)+      | otherwise  = case LL.break cpred s of+        (str', tail')+          | LL.null tail' -> eneeCheckIfDone (liftI . step) . k $ Chunk str'+          | otherwise     -> idone (k $ Chunk str') (Chunk tail')+  step k stream           =  idone (k stream) stream+{-# INLINE breakE #-}+ -- |Read n elements from a stream and apply the given iteratee to the -- stream of the read elements. Unless the stream is terminated early, we -- read exactly n elements, even if the iteratee has accepted fewer.@@ -577,8 +601,8 @@       -> Iteratee s m () mapM_ f = liftI step   where-    step (Chunk xs) | LL.null xs = mapM_ f-    step (Chunk xs) = lift (LL.mapM_ f xs) >> mapM_ f+    step (Chunk xs) | LL.null xs = liftI step+    step (Chunk xs) = lift (LL.mapM_ f xs) >> liftI step     step s@(EOF _)  = idone () s {-# INLINE mapM_ #-} 
src/Data/NullPoint.hs view
@@ -9,6 +9,7 @@ where  import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L  -- ---------------------------------------------- -- |NullPoint class.  Containers that have a null representation, corresponding@@ -22,3 +23,5 @@ instance NullPoint B.ByteString where   empty = B.empty +instance NullPoint L.ByteString where+  empty = L.empty
src/Data/Nullable.hs view
@@ -9,6 +9,7 @@  import Data.NullPoint import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L   -- ----------------------------------------------@@ -22,3 +23,6 @@  instance Nullable B.ByteString where   nullC = B.null++instance Nullable L.ByteString where+  nullC = L.null
+ tests/foo.hs view
@@ -0,0 +1,20 @@+import Data.ByteString (ByteString)+import Data.Iteratee as I+import Data.Iteratee.Char+import System++main = do+        args <- getArgs+        let fname     = args !! 0+        let blockSize = read $ args !! 1++        fileDriver (leak blockSize) fname >>= print++leak :: Int -> Iteratee ByteString IO ()+leak blockSize = chunkedRead+    where+        consChunk :: Iteratee ByteString IO String+        consChunk = (joinI $ I.take blockSize I.length) >>= return . show++        chunkedRead :: Iteratee ByteString IO ()+        chunkedRead = joinI $ convStream consChunk printLinesUnterminated
tests/testIteratee.hs view
@@ -91,6 +91,13 @@ prop_break2 f xs = runner1 (enumPure1Chunk xs (Iter.break f >> stream2list)) == snd (break f xs)   where types = xs :: [Int] +prop_breakE f xs = runner1 (enumPure1Chunk xs (joinI $ Iter.breakE f stream2stream)) == fst (break f xs)+  where types = xs :: [Int]++prop_breakE2 f xs = runner1 (enumPure1Chunk xs (joinI (Iter.breakE f stream2stream) >> stream2list)) == snd (break f xs)+  where types = xs :: [Int]++ prop_head xs = P.length xs > 0 ==> runner1 (enumPure1Chunk xs Iter.head) == head xs   where types = xs :: [Int] @@ -260,7 +267,7 @@   ]   ,testGroup "Simple Iteratees" [     testProperty "break" prop_break-    ,testProperty "break remaineder" prop_break2+    ,testProperty "break remainder" prop_break2     ,testProperty "head" prop_head     ,testProperty "head remainder" prop_head2     ,testProperty "heads" prop_heads@@ -289,6 +296,8 @@     testProperty "mapStream identity" prop_mapStream     ,testProperty "mapStream identity 2" prop_mapStream2     ,testProperty "mapStream identity joinI" prop_mapjoin+    ,testProperty "breakE" prop_breakE+    ,testProperty "breakE remainder" prop_breakE2     ,testProperty "take" prop_take     ,testProperty "take (finished iteratee)" prop_take2     ,testProperty "takeUpTo" prop_takeUpTo