enumerator 0.3.0.1 → 0.4
raw patch · 7 files changed
+114/−125 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.Enumerator: instance (Monad m) => Applicative (Iteratee e a m)
- Data.Enumerator: instance (Monad m) => Functor (Iteratee e a m)
- Data.Enumerator: instance (Monad m) => Monad (Iteratee e a m)
- Data.Enumerator: instance (MonadIO m) => MonadIO (Iteratee e a m)
- Data.Enumerator: instance MonadTrans (Iteratee e a)
- Data.Enumerator: mapError :: (Monad m) => (e1 -> e2) -> Step e1 a m b -> Iteratee e2 a m b
+ Data.Enumerator: instance (Monad m) => Applicative (Iteratee a m)
+ Data.Enumerator: instance (Monad m) => Functor (Iteratee a m)
+ Data.Enumerator: instance (Monad m) => Monad (Iteratee a m)
+ Data.Enumerator: instance (MonadIO m) => MonadIO (Iteratee a m)
+ Data.Enumerator: instance MonadTrans (Iteratee a)
- Data.Enumerator: ($$) :: (Monad m) => (Step e a m b -> Iteratee e' a' m b') -> Iteratee e a m b -> Iteratee e' a' m b'
+ Data.Enumerator: ($$) :: (Monad m) => (Step a m b -> Iteratee a' m b') -> Iteratee a m b -> Iteratee a' m b'
- Data.Enumerator: (<==<) :: (Monad m) => (Step e a m b -> Iteratee e' a' m b') -> Enumerator e a m b -> Step e a m b -> Iteratee e' a' m b'
+ Data.Enumerator: (<==<) :: (Monad m) => (Step a m b -> Iteratee a' m b') -> Enumerator a m b -> Step a m b -> Iteratee a' m b'
- Data.Enumerator: (==<<) :: (Monad m) => (Step e a m b -> Iteratee e' a' m b') -> Iteratee e a m b -> Iteratee e' a' m b'
+ Data.Enumerator: (==<<) :: (Monad m) => (Step a m b -> Iteratee a' m b') -> Iteratee a m b -> Iteratee a' m b'
- Data.Enumerator: (>==>) :: (Monad m) => Enumerator e a m b -> (Step e a m b -> Iteratee e' a' m b') -> Step e a m b -> Iteratee e' a' m b'
+ Data.Enumerator: (>==>) :: (Monad m) => Enumerator a m b -> (Step a m b -> Iteratee a' m b') -> Step a m b -> Iteratee a' m b'
- Data.Enumerator: (>>==) :: (Monad m) => Iteratee e a m b -> (Step e a m b -> Iteratee e' a' m b') -> Iteratee e' a' m b'
+ Data.Enumerator: (>>==) :: (Monad m) => Iteratee a m b -> (Step a m b -> Iteratee a' m b') -> Iteratee a' m b'
- Data.Enumerator: Continue :: (Stream a -> Iteratee e a m b) -> Step e a m b
+ Data.Enumerator: Continue :: (Stream a -> Iteratee a m b) -> Step a m b
- Data.Enumerator: Error :: e -> Step e a m b
+ Data.Enumerator: Error :: SomeException -> Step a m b
- Data.Enumerator: Iteratee :: m (Step e a m b) -> Iteratee e a m b
+ Data.Enumerator: Iteratee :: m (Step a m b) -> Iteratee a m b
- Data.Enumerator: Yield :: b -> (Stream a) -> Step e a m b
+ Data.Enumerator: Yield :: b -> (Stream a) -> Step a m b
- Data.Enumerator: break :: (Monad m) => (a -> Bool) -> Iteratee e a m [a]
+ Data.Enumerator: break :: (Monad m) => (a -> Bool) -> Iteratee a m [a]
- Data.Enumerator: catchError :: (Monad m) => Iteratee e a m b -> (e -> Iteratee e a m b) -> Iteratee e a m b
+ Data.Enumerator: catchError :: (Monad m) => Iteratee a m b -> (SomeException -> Iteratee a m b) -> Iteratee a m b
- Data.Enumerator: checkDone :: (Monad m) => ((Stream a -> Iteratee e a m b) -> Iteratee e a' m (Step e a m b)) -> Enumeratee e a' a m b
+ Data.Enumerator: checkDone :: (Monad m) => ((Stream a -> Iteratee a m b) -> Iteratee a' m (Step a m b)) -> Enumeratee a' a m b
- Data.Enumerator: concatEnums :: (Monad m) => [Enumerator e a m b] -> Enumerator e a m b
+ Data.Enumerator: concatEnums :: (Monad m) => [Enumerator a m b] -> Enumerator a m b
- Data.Enumerator: consume :: (Monad m) => Iteratee e a m [a]
+ Data.Enumerator: consume :: (Monad m) => Iteratee a m [a]
- Data.Enumerator: continue :: (Monad m) => (Stream a -> Iteratee e a m b) -> Iteratee e a m b
+ Data.Enumerator: continue :: (Monad m) => (Stream a -> Iteratee a m b) -> Iteratee a m b
- Data.Enumerator: data Step e a m b
+ Data.Enumerator: data Step a m b
- Data.Enumerator: drop :: (Monad m) => Integer -> Iteratee e a m ()
+ Data.Enumerator: drop :: (Monad m) => Integer -> Iteratee a m ()
- Data.Enumerator: dropWhile :: (Monad m) => (a -> Bool) -> Iteratee e a m ()
+ Data.Enumerator: dropWhile :: (Monad m) => (a -> Bool) -> Iteratee a m ()
- Data.Enumerator: enumEOF :: (Monad m) => Enumerator e a m b
+ Data.Enumerator: enumEOF :: (Monad m) => Enumerator a m b
- Data.Enumerator: enumList :: (Monad m) => Integer -> [a] -> Enumerator e a m b
+ Data.Enumerator: enumList :: (Monad m) => Integer -> [a] -> Enumerator a m b
- Data.Enumerator: head :: (Monad m) => Iteratee e a m (Maybe a)
+ Data.Enumerator: head :: (Monad m) => Iteratee a m (Maybe a)
- Data.Enumerator: isEOF :: (Monad m) => Iteratee e a m Bool
+ Data.Enumerator: isEOF :: (Monad m) => Iteratee a m Bool
- Data.Enumerator: joinI :: (Monad m) => Iteratee e a m (Step e a' m b) -> Iteratee e a m b
+ Data.Enumerator: joinI :: (Monad m) => Iteratee a m (Step a' m b) -> Iteratee a m b
- Data.Enumerator: last :: (Monad m) => Iteratee e a m (Maybe a)
+ Data.Enumerator: last :: (Monad m) => Iteratee a m (Maybe a)
- Data.Enumerator: length :: (Monad m) => Iteratee e a m Integer
+ Data.Enumerator: length :: (Monad m) => Iteratee a m Integer
- Data.Enumerator: liftFoldL :: (Monad m) => (b -> a -> b) -> b -> Iteratee e a m b
+ Data.Enumerator: liftFoldL :: (Monad m) => (b -> a -> b) -> b -> Iteratee a m b
- Data.Enumerator: liftFoldL' :: (Monad m) => (b -> a -> b) -> b -> Iteratee e a m b
+ Data.Enumerator: liftFoldL' :: (Monad m) => (b -> a -> b) -> b -> Iteratee a m b
- Data.Enumerator: liftFoldM :: (Monad m) => (b -> a -> m b) -> b -> Iteratee e a m b
+ Data.Enumerator: liftFoldM :: (Monad m) => (b -> a -> m b) -> b -> Iteratee a m b
- Data.Enumerator: liftI :: (Monad m) => (Stream a -> Step e a m b) -> Iteratee e a m b
+ Data.Enumerator: liftI :: (Monad m) => (Stream a -> Step a m b) -> Iteratee a m b
- Data.Enumerator: liftTrans :: (Monad m, MonadTrans t, Monad (t m)) => Iteratee e a m b -> Iteratee e a (t m) b
+ Data.Enumerator: liftTrans :: (Monad m, MonadTrans t, Monad (t m)) => Iteratee a m b -> Iteratee a (t m) b
- Data.Enumerator: map :: (Monad m) => (ao -> ai) -> Enumeratee e ao ai m b
+ Data.Enumerator: map :: (Monad m) => (ao -> ai) -> Enumeratee ao ai m b
- Data.Enumerator: newtype Iteratee e a m b
+ Data.Enumerator: newtype Iteratee a m b
- Data.Enumerator: peek :: (Monad m) => Iteratee e a m (Maybe a)
+ Data.Enumerator: peek :: (Monad m) => Iteratee a m (Maybe a)
- Data.Enumerator: printChunks :: (MonadIO m, Show a) => Bool -> Iteratee e a m ()
+ Data.Enumerator: printChunks :: (MonadIO m, Show a) => Bool -> Iteratee a m ()
- Data.Enumerator: returnI :: (Monad m) => Step e a m b -> Iteratee e a m b
+ Data.Enumerator: returnI :: (Monad m) => Step a m b -> Iteratee a m b
- Data.Enumerator: run :: (Monad m) => Iteratee e a m b -> m (Either e b)
+ Data.Enumerator: run :: (Monad m) => Iteratee a m b -> m (Either SomeException b)
- Data.Enumerator: runIteratee :: Iteratee e a m b -> m (Step e a m b)
+ Data.Enumerator: runIteratee :: Iteratee a m b -> m (Step a m b)
- Data.Enumerator: sequence :: (Monad m) => Iteratee e ao m ai -> Enumeratee e ao ai m b
+ Data.Enumerator: sequence :: (Monad m) => Iteratee ao m ai -> Enumeratee ao ai m b
- Data.Enumerator: span :: (Monad m) => (a -> Bool) -> Iteratee e a m [a]
+ Data.Enumerator: span :: (Monad m) => (a -> Bool) -> Iteratee a m [a]
- Data.Enumerator: throwError :: (Monad m) => e -> Iteratee e a m b
+ Data.Enumerator: throwError :: (Monad m, Exception e) => e -> Iteratee a m b
- Data.Enumerator: type Enumeratee e aOut aIn m b = Step e aIn m b -> Iteratee e aOut m (Step e aIn m b)
+ Data.Enumerator: type Enumeratee aOut aIn m b = Step aIn m b -> Iteratee aOut m (Step aIn m b)
- Data.Enumerator: type Enumerator e a m b = Step e a m b -> Iteratee e a m b
+ Data.Enumerator: type Enumerator a m b = Step a m b -> Iteratee a m b
- Data.Enumerator: yield :: (Monad m) => b -> Stream a -> Iteratee e a m b
+ Data.Enumerator: yield :: (Monad m) => b -> Stream a -> Iteratee a m b
- Data.Enumerator.IO: enumFile :: FilePath -> Enumerator SomeException ByteString IO b
+ Data.Enumerator.IO: enumFile :: FilePath -> Enumerator ByteString IO b
- Data.Enumerator.IO: enumHandle :: Integer -> Handle -> Enumerator SomeException ByteString IO b
+ Data.Enumerator.IO: enumHandle :: Integer -> Handle -> Enumerator ByteString IO b
- Data.Enumerator.IO: iterHandle :: Handle -> Iteratee SomeException ByteString IO ()
+ Data.Enumerator.IO: iterHandle :: Handle -> Iteratee ByteString IO ()
- Data.Enumerator.Text: decode :: (Monad m) => Codec -> Enumeratee SomeException ByteString Text m b
+ Data.Enumerator.Text: decode :: (Monad m) => Codec -> Enumeratee ByteString Text m b
- Data.Enumerator.Text: encode :: (Monad m) => Codec -> Enumeratee SomeException Text ByteString m b
+ Data.Enumerator.Text: encode :: (Monad m) => Codec -> Enumeratee Text ByteString m b
- Data.Enumerator.Text: enumFile :: FilePath -> Enumerator SomeException Text IO b
+ Data.Enumerator.Text: enumFile :: FilePath -> Enumerator Text IO b
- Data.Enumerator.Text: enumHandle :: Handle -> Enumerator SomeException Text IO b
+ Data.Enumerator.Text: enumHandle :: Handle -> Enumerator Text IO b
- Data.Enumerator.Text: iterHandle :: Handle -> Iteratee SomeException Text IO ()
+ Data.Enumerator.Text: iterHandle :: Handle -> Iteratee Text IO ()
Files
- Examples/cat.hs +37/−32
- Examples/wc.hs +3/−6
- enumerator.cabal +1/−1
- hs/Data/Enumerator.hs +64/−75
- hs/Data/Enumerator/IO.hs +3/−3
- hs/Data/Enumerator/Text.hs +5/−5
- hs/Data/Enumerator/Util.hs +1/−3
Examples/cat.hs view
@@ -14,6 +14,7 @@ import qualified Data.ByteString as B import qualified Foreign as F import System.IO+import System.IO.Error (isEOFError) import System.Environment (getArgs) -- The following definitions of 'enumHandle', 'enumFile', and 'iterHandle' are@@ -22,47 +23,51 @@ enumHandle :: Integer -- ^ Buffer size -> Handle- -> Enumerator SomeException B.ByteString IO b-enumHandle bufferSize h = Iteratee . io where+ -> Enumerator B.ByteString IO b+enumHandle bufferSize h = Iteratee . loop where intSize = fromInteger bufferSize - -- Allocate a single buffer for reading from the file- io step = F.allocaBytes intSize $ \p -> loop step p- -- If more input is required before the enumerator's iteratee can- -- yield a result, feed it from the handle. If a different step is- -- received ('Error' or 'Yield'), just pass it through.- loop (Continue k) = read' k- loop step = const $ return step- - read' k p = do+ -- yield a result, feed it from the handle.+ loop (Continue k) = do -- While not strictly necessary to proper operation, catching -- exceptions here allows more unified exception handling when -- the enumerator/iteratee is run.- eitherN <- E.try $ hGetBuf h p intSize- case eitherN of+ eitherBytes <- E.try $ do+ + -- The enumerator must function normally when the+ -- handle is something like a slow file, or network+ -- socket; if there's not enough data to fill the+ -- buffer yet, a partial read is returned.+ hasInput <- E.catch+ (hWaitForInput h (1))+ (\err -> if isEOFError err+ then return False+ else E.throwIO err)+ + -- An EOF is represented by the empty bytestring+ if hasInput+ then B.hGetNonBlocking h intSize+ else return B.empty+ + case eitherBytes of+ -- Interacting with the socket threw an IO error of+ -- some sort Left err -> return $ Error err - -- if 'hGetBuf' returns 0, then the handle has reached- -- EOF. The enumerator has two choices:- --- -- * Send EOF to its iteratee, and return the result- -- * Return a Continue, with the current continuation- --- -- The second is better, because it allows enumerators- -- to be composed with (>>==). If EOF is sent, only- -- one enumerator can be read at a time.- Right 0 -> return $ Continue k+ -- The socket has reached EOF; pass control to the+ -- next enumerator+ Right bytes | B.null bytes -> return (Continue k) - -- 'hGetBuf' was at least partially successful, so read- -- bytes into a ByteString and pass it through to the- -- iteratee.- Right n -> do- bytes <- B.packCStringLen (p, n)- step <- runIteratee (k (Chunks [bytes]))- loop step p+ -- Bytes were read successfully; feed them to the+ -- iteratee and continue looping+ Right bytes -> runIteratee (k (Chunks [bytes])) >>= loop+ + -- If a different step is received ('Error' or 'Yield'), just pass+ -- it through.+ loop step = return step -enumFile :: FilePath -> Enumerator E.SomeException B.ByteString IO b+enumFile :: FilePath -> Enumerator B.ByteString IO b enumFile path s = Iteratee $ do -- Opening the file can be performed either inside or outside of the -- Iteratee. Inside allows exceptions to be caught and propagated@@ -77,7 +82,7 @@ -- 'iterHandle' is the opposite of 'enumHandle', in that it *writes to* a -- handle instead of reading from it. An enumerator is a source, an iteratee -- is a sink.-iterHandle :: Handle -> Iteratee SomeException B.ByteString IO ()+iterHandle :: Handle -> Iteratee B.ByteString IO () -- Most iteratees start in the 'Continue' state, as they need some -- input before they can produce any value.
Examples/wc.hs view
@@ -29,7 +29,7 @@ -- iterBytes simply counts how many bytes are in each chunk, accumulates this -- count, and returns it when EOF is received -iterBytes :: Monad m => Iteratee e B.ByteString m Integer+iterBytes :: Monad m => Iteratee B.ByteString m Integer iterBytes = continue (step 0) where step acc EOF = yield acc EOF step acc (Chunks xs) = continue $ step $! foldl' foldStep acc xs@@ -40,7 +40,7 @@ -- Because it's basically the same as 'iterBytes', we use it to demonstrate -- the 'liftFoldL\'' helper function. -iterLines :: Monad m => Iteratee e B.ByteString m Integer+iterLines :: Monad m => Iteratee B.ByteString m Integer iterLines = liftFoldL' step 0 where step acc bytes = acc + countChar '\n' bytes countChar c = B8.foldl (\acc c' -> if c' == c then acc + 1 else acc) 0@@ -49,14 +49,11 @@ -- assuming UTF-8) before performing any counting. Leftover bytes, not part -- of a valid UTF-8 character, are yielded as surplus ----- Since it's possible for the input file's encoding to be non-UTF8, a bit--- of error handling is also required.--- -- Note the use of joinI. 'ET.decode' is an enumeratee, which means it returns -- an iteratee yielding an inner step. 'joinI' "collapses" an enumeratee's -- return value, much as 'join' does to monadic values. -iterChars :: Monad m => Iteratee E.SomeException B.ByteString m Integer+iterChars :: Monad m => Iteratee B.ByteString m Integer iterChars = joinI (ET.decode ET.utf8 $$ count) where count = liftFoldL' (\acc t -> acc + toInteger (T.length t)) 0
enumerator.cabal view
@@ -1,5 +1,5 @@ name: enumerator-version: 0.3.0.1+version: 0.4 synopsis: Implementation of Oleg Kiselyov's left-fold enumerators license: MIT license-file: license.txt
hs/Data/Enumerator.hs view
@@ -26,7 +26,6 @@ , continue , throwError , catchError- , mapError , liftI , (>>==) , (==<<)@@ -66,15 +65,14 @@ , Data.Enumerator.break ) where import Data.List (genericDrop, genericLength, genericSplitAt)+import qualified Control.Exception as E import Data.Monoid (Monoid, mempty, mappend, mconcat) import qualified Control.Applicative as A import Control.Monad (liftM, ap) import qualified Control.Monad.IO.Class as MIO import qualified Control.Monad.Trans.Class as MT-import Control.Monad.Fix (fix) import qualified Data.List as DataList import Control.Monad (foldM)-import qualified Control.Exception as E import Prelude hiding (span) import qualified Prelude as Prelude -- | Not to be confused with types from the @Stream@ or@@ -89,11 +87,11 @@ = Chunks [a] | EOF deriving (Show, Eq)-data Step e a m b+data Step a m b -- | The 'Iteratee' is capable of accepting more input. Note that more input -- is not necessarily required; the 'Iteratee' might be able to generate a -- value immediately if it receives 'EOF'.- = Continue (Stream a -> Iteratee e a m b)+ = Continue (Stream a -> Iteratee a m b) -- | The 'Iteratee' has received enough input to generate a result. -- Included in this value is left-over input, which can be passed to@@ -101,9 +99,8 @@ | Yield b (Stream a) -- | The 'Iteratee' encountered an error which prevents it from proceeding- -- further. The type of error will depend on the 'Enumerator' and/or- -- 'Iteratee' -- common choices are 'String' and 'E.SomeException'.- | Error e+ -- further.+ | Error E.SomeException -- | The primary data type for this library, which consumes -- input from a 'Stream' until it either generates a value or encounters@@ -114,24 +111,24 @@ -- passed to the continuation, the iteratee returns the next step: -- 'Continue' for more data, 'Yield' when it's finished, or 'Error' to -- abort processing.-newtype Iteratee e a m b = Iteratee- { runIteratee :: m (Step e a m b)+newtype Iteratee a m b = Iteratee+ { runIteratee :: m (Step a m b) } -- | While 'Iteratee's consume data, enumerators generate it. Since--- @'Iteratee'@ is an alias for @m ('Step' e a m b)@, 'Enumerator's can+-- @'Iteratee'@ is an alias for @m ('Step' a m b)@, 'Enumerator's can -- be considered step transformers of type--- @'Step' e a m b -> m ('Step' e a m b)@.+-- @'Step' a m b -> m ('Step' a m b)@. -- -- 'Enumerator's typically read from an external source (parser, handle, -- random generator, etc). They feed chunks into an 'Iteratee' until the -- source runs out of data (triggering 'EOF') or the iteratee finishes -- processing ('Yield's a value).-type Enumerator e a m b = Step e a m b -> Iteratee e a m b+type Enumerator a m b = Step a m b -> Iteratee a m b -- | In cases where an enumerator acts as both a source and sink, the resulting -- type is named an 'Enumeratee'. Enumeratees have two input types, -- “outer a” (@aOut@) and “inner a” (@aIn@).-type Enumeratee e aOut aIn m b = Step e aIn m b -> Iteratee e aOut m (Step e aIn m b)+type Enumeratee aOut aIn m b = Step aIn m b -> Iteratee aOut m (Step aIn m b) instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks $ mappend xs ys@@ -145,7 +142,7 @@ return = Chunks . return Chunks xs >>= f = mconcat $ fmap f xs EOF >>= _ = EOF-instance Monad m => Monad (Iteratee e a m) where+instance Monad m => Monad (Iteratee a m) where return x = Iteratee . return $ Yield x $ Chunks [] {-# INLINE return #-} @@ -159,27 +156,27 @@ Continue k -> runIteratee $ k chunk Error err -> return $ Error err Yield x' _ -> return $ Yield x' chunk-instance Monad m => Functor (Iteratee e a m) where+instance Monad m => Functor (Iteratee a m) where fmap = liftM {-# INLINE fmap #-} -instance Monad m => A.Applicative (Iteratee e a m) where+instance Monad m => A.Applicative (Iteratee a m) where pure = return {-# INLINE pure #-} (<*>) = ap {-# INLINE (<*>) #-}-instance MT.MonadTrans (Iteratee e a) where+instance MT.MonadTrans (Iteratee a) where lift m = Iteratee $ m >>= runIteratee . return {-# INLINE lift #-} -instance MIO.MonadIO m => MIO.MonadIO (Iteratee e a m) where+instance MIO.MonadIO m => MIO.MonadIO (Iteratee a m) where liftIO = MT.lift . MIO.liftIO {-# INLINE liftIO #-} -- | Lift an 'Iteratee' onto a monad transformer, re-wrapping the -- 'Iteratee'’s inner monadic values. liftTrans :: (Monad m, MT.MonadTrans t, Monad (t m)) =>- Iteratee e a m b -> Iteratee e a (t m) b+ Iteratee a m b -> Iteratee a (t m) b liftTrans iter = Iteratee $ do step <- MT.lift $ runIteratee iter return $ case step of@@ -187,60 +184,52 @@ Error err -> Error err Continue k -> Continue (liftTrans . k) -- | @returnI x = Iteratee (return x)@-returnI :: Monad m => Step e a m b -> Iteratee e a m b+returnI :: Monad m => Step a m b -> Iteratee a m b returnI = Iteratee . return {-# INLINE returnI #-} -- | @yield x chunk = returnI (Yield x chunk)@-yield :: Monad m => b -> Stream a -> Iteratee e a m b+yield :: Monad m => b -> Stream a -> Iteratee a m b yield x chunk = returnI (Yield x chunk) {-# INLINE yield #-} -- | @continue k = returnI (Continue k)@-continue :: Monad m => (Stream a -> Iteratee e a m b) -> Iteratee e a m b+continue :: Monad m => (Stream a -> Iteratee a m b) -> Iteratee a m b continue = returnI . Continue {-# INLINE continue #-} -- | @throwError err = returnI (Error err)@-throwError :: Monad m => e -> Iteratee e a m b-throwError = returnI . Error+throwError :: (Monad m, E.Exception e) => e -> Iteratee a m b+throwError = returnI . Error . E.SomeException {-# INLINE throwError #-} -- | @liftI f = continue (returnI . f)@-liftI :: Monad m => (Stream a -> Step e a m b) -> Iteratee e a m b+liftI :: Monad m => (Stream a -> Step a m b) -> Iteratee a m b liftI k = continue $ returnI . k {-# INLINE liftI #-}-catchError :: Monad m => Iteratee e a m b -> (e -> Iteratee e a m b) -> Iteratee e a m b+catchError :: Monad m => Iteratee a m b -> (E.SomeException -> Iteratee a m b) -> Iteratee a m b catchError iter h = Iteratee $ do step <- runIteratee iter case step of Error err -> runIteratee (h err) _ -> return step--- | A pseudo-'Enumerator' which alters the error representation of its--- iteratee. Use this to compose enumerators and iteratees with differing--- or sub-optimal error types.-mapError :: Monad m => (e1 -> e2) -> Step e1 a m b -> Iteratee e2 a m b-mapError conv = fix $ \loop s -> case s of- Yield x chunks -> yield x chunks- Continue k -> continue ((loop $$) . k)- Error err -> throwError (conv err) infixl 1 >>== -- | Equivalent to (>>=), but allows 'Iteratee's with different input types -- to be composed. (>>==) :: Monad m =>- Iteratee e a m b ->- (Step e a m b -> Iteratee e' a' m b') ->- Iteratee e' a' m b'+ Iteratee a m b ->+ (Step a m b -> Iteratee a' m b') ->+ Iteratee a' m b' i >>== f = Iteratee $ runIteratee i >>= runIteratee . f {-# INLINE (>>==) #-} infixr 1 ==<< -- | @(==\<\<) = flip (\>\>==)@ (==<<):: Monad m =>- (Step e a m b -> Iteratee e' a' m b') ->- Iteratee e a m b ->- Iteratee e' a' m b'+ (Step a m b -> Iteratee a' m b') ->+ Iteratee a m b ->+ Iteratee a' m b' (==<<) = flip (>>==) {-# INLINE (==<<) #-} infixr 0 $$@@ -250,52 +239,52 @@ -- This might be easier to read when passing a chain of iteratees to an -- enumerator. ($$):: Monad m =>- (Step e a m b -> Iteratee e' a' m b') ->- Iteratee e a m b ->- Iteratee e' a' m b'+ (Step a m b -> Iteratee a' m b') ->+ Iteratee a m b ->+ Iteratee a' m b' ($$) = (==<<) {-# INLINE ($$) #-} infixr 1 >==> -- | @(>==>) e1 e2 s = e1 s >>== e2@ (>==>) :: Monad m =>- Enumerator e a m b ->- (Step e a m b -> Iteratee e' a' m b') ->- Step e a m b ->- Iteratee e' a' m b'+ Enumerator a m b ->+ (Step a m b -> Iteratee a' m b') ->+ Step a m b ->+ Iteratee a' m b' (>==>) e1 e2 s = e1 s >>== e2 {-# INLINE (>==>) #-} infixr 1 <==< -- | @(\<==\<) = flip (>==>)@ (<==<) :: Monad m =>- (Step e a m b -> Iteratee e' a' m b') ->- Enumerator e a m b ->- Step e a m b ->- Iteratee e' a' m b'+ (Step a m b -> Iteratee a' m b') ->+ Enumerator a m b ->+ Step a m b ->+ Iteratee a' m b' (<==<) = flip (>==>) {-# INLINE (<==<) #-} -- | Consume all input until 'EOF', then return consumed input as a list.-consume :: Monad m => Iteratee e a m [a]+consume :: Monad m => Iteratee a m [a] consume = liftI $ step id where step acc chunk = case chunk of Chunks [] -> Continue $ returnI . step acc Chunks xs -> Continue $ returnI . (step $ acc . (xs ++)) EOF -> Yield (acc []) EOF -- | Return 'True' if the next 'Stream' is 'EOF'.-isEOF :: Monad m => Iteratee e a m Bool+isEOF :: Monad m => Iteratee a m Bool isEOF = liftI $ \c -> case c of EOF -> Yield True c _ -> Yield False c -- | Lifts a pure left fold into an iteratee.-liftFoldL :: Monad m => (b -> a -> b) -> b -> Iteratee e a m b+liftFoldL :: Monad m => (b -> a -> b) -> b -> Iteratee a m b liftFoldL f = liftI . step where step acc chunk = case chunk of Chunks [] -> Continue $ returnI . step acc Chunks xs -> Continue $ returnI . step (Prelude.foldl f acc xs) EOF -> Yield acc EOF -- | As 'liftFoldL', but strict in its accumulator.-liftFoldL' :: Monad m => (b -> a -> b) -> b -> Iteratee e a m b+liftFoldL' :: Monad m => (b -> a -> b) -> b -> Iteratee a m b liftFoldL' f = liftI . step where fold = DataList.foldl' f step acc chunk = case chunk of@@ -303,7 +292,7 @@ Chunks xs -> Continue $ returnI . (step $! fold acc xs) EOF -> Yield acc EOF -- | Lifts a monadic left fold into an iteratee.-liftFoldM :: Monad m => (b -> a -> m b) -> b -> Iteratee e a m b+liftFoldM :: Monad m => (b -> a -> m b) -> b -> Iteratee a m b liftFoldM f = continue . step where step acc chunk = case chunk of Chunks [] -> continue $ step acc@@ -311,7 +300,7 @@ EOF -> yield acc EOF -- | Run an iteratee until it finishes, and return either the final value -- (if it succeeded) or the error (if it failed).-run :: Monad m => Iteratee e a m b -> m (Either e b)+run :: Monad m => Iteratee a m b -> m (Either E.SomeException b) run i = do mStep <- runIteratee $ enumEOF ==<< i case mStep of@@ -320,7 +309,7 @@ Continue _ -> error "run: divergent iteratee" -- | Print chunks as they're received from the enumerator, optionally -- printing empty chunks.-printChunks :: (MIO.MonadIO m, Show a) => Bool -> Iteratee e a m ()+printChunks :: (MIO.MonadIO m, Show a) => Bool -> Iteratee a m () printChunks printEmpty = continue step where step (Chunks []) | not printEmpty = continue step step (Chunks xs) = MIO.liftIO (print xs) >> continue step@@ -328,7 +317,7 @@ -- | The most primitive enumerator; simply sends 'EOF'. The iteratee must -- either yield a value or throw an error continuing receiving 'EOF' will -- not terminate with any useful value.-enumEOF :: Monad m => Enumerator e a m b+enumEOF :: Monad m => Enumerator a m b enumEOF (Yield x _) = yield x EOF enumEOF (Error err) = throwError err enumEOF (Continue k) = k EOF >>== check where@@ -337,19 +326,19 @@ -- | Another small, useful enumerator separates an input list into chunks, -- and sends them to the iteratee. This is useful for testing iteratees in pure -- code.-enumList :: Monad m => Integer -> [a] -> Enumerator e a m b+enumList :: Monad m => Integer -> [a] -> Enumerator a m b enumList n xs (Continue k) | not (null xs) = k chunk >>== loop where (s1, s2) = genericSplitAt n xs chunk = Chunks s1 loop = enumList n s2 enumList _ _ step = returnI step -- | Compose a list of 'Enumerator's using '(>>==)'-concatEnums :: Monad m => [Enumerator e a m b] -> Enumerator e a m b+concatEnums :: Monad m => [Enumerator a m b] -> Enumerator a m b concatEnums = foldl (>==>) returnI {-# INLINE concatEnums #-} -- | 'joinI' is used to “flatten” 'Enumeratee's into an -- 'Iteratee'.-joinI :: Monad m => Iteratee e a m (Step e a' m b) -> Iteratee e a m b+joinI :: Monad m => Iteratee a m (Step a' m b) -> Iteratee a m b joinI outer = outer >>= check where check (Continue k) = k EOF >>== \s -> case s of Continue _ -> error "joinI: divergent iteratee"@@ -361,36 +350,36 @@ -- 'checkDone' passes its parameter a continuation if the 'Iteratee' -- can still consume input, or yields otherwise. checkDone :: Monad m =>- ((Stream a -> Iteratee e a m b) -> Iteratee e a' m (Step e a m b)) ->- Enumeratee e a' a m b+ ((Stream a -> Iteratee a m b) -> Iteratee a' m (Step a m b)) ->+ Enumeratee a' a m b checkDone _ (Yield x chunk) = return $ Yield x chunk checkDone f (Continue k) = f k checkDone _ (Error err) = throwError err {-# INLINE checkDone #-}-map :: Monad m => (ao -> ai) -> Enumeratee e ao ai m b+map :: Monad m => (ao -> ai) -> Enumeratee ao ai m b map f = loop where loop = checkDone $ continue . step step k EOF = yield (Continue k) EOF step k (Chunks []) = continue $ step k step k (Chunks xs) = k (Chunks (Prelude.map f xs)) >>== loop-sequence :: Monad m => Iteratee e ao m ai -> Enumeratee e ao ai m b+sequence :: Monad m => Iteratee ao m ai -> Enumeratee ao ai m b sequence i = loop where loop = checkDone check check k = isEOF >>= \f -> if f then yield (Continue k) EOF else step k step k = i >>= \v -> k (Chunks [v]) >>== loop-head :: Monad m => Iteratee e a m (Maybe a)+head :: Monad m => Iteratee a m (Maybe a) head = liftI step where step (Chunks []) = Continue $ returnI . step step (Chunks (x:xs)) = Yield (Just x) (Chunks xs) step EOF = Yield Nothing EOF-peek :: Monad m => Iteratee e a m (Maybe a)+peek :: Monad m => Iteratee a m (Maybe a) peek = liftI step where step (Chunks []) = Continue $ returnI . step step chunk@(Chunks (x:_)) = Yield (Just x) chunk step chunk = Yield Nothing chunk-last :: Monad m => Iteratee e a m (Maybe a)+last :: Monad m => Iteratee a m (Maybe a) last = liftI $ step Nothing where step ret (Chunks xs) = let ret' = case xs of@@ -398,11 +387,11 @@ _ -> Just $ Prelude.last xs in Continue $ returnI . step ret' step ret EOF = Yield ret EOF-length :: Monad m => Iteratee e a m Integer+length :: Monad m => Iteratee a m Integer length = liftI $ step 0 where step n (Chunks xs) = Continue $ returnI . step (n + genericLength xs) step n EOF = Yield n EOF-drop :: Monad m => Integer -> Iteratee e a m ()+drop :: Monad m => Integer -> Iteratee a m () drop 0 = return () drop n = liftI $ step n where step n' (Chunks xs)@@ -410,13 +399,13 @@ | otherwise = Yield () $ Chunks $ genericDrop n' xs step _ EOF = Yield () EOF len = genericLength-dropWhile :: Monad m => (a -> Bool) -> Iteratee e a m ()+dropWhile :: Monad m => (a -> Bool) -> Iteratee a m () dropWhile p = liftI step where step (Chunks xs) = case Prelude.dropWhile p xs of [] -> Continue $ returnI . step xs' -> Yield () $ Chunks xs' step EOF = Yield () EOF-span :: Monad m => (a -> Bool) -> Iteratee e a m [a]+span :: Monad m => (a -> Bool) -> Iteratee a m [a] span f = liftI $ step [] where step acc (Chunks xs) = case Prelude.span f xs of (_, []) -> Continue $ returnI . step (acc ++ xs)@@ -424,5 +413,5 @@ step acc EOF = Yield acc EOF -- | @break p = 'span' (not . p)@-break :: Monad m => (a -> Bool) -> Iteratee e a m [a]+break :: Monad m => (a -> Bool) -> Iteratee a m [a] break p = span $ not . p
hs/Data/Enumerator/IO.hs view
@@ -34,7 +34,7 @@ -- 'IO.ReadWriteMode'. enumHandle :: Integer -- ^ Buffer size -> IO.Handle- -> Enumerator E.SomeException B.ByteString IO b+ -> Enumerator B.ByteString IO b enumHandle bufferSize h = Iteratee . loop where loop (Continue k) = withBytes $ \bytes -> if B.null bytes then return $ Continue k@@ -54,7 +54,7 @@ else return B.empty -- | Opens a file path in binary mode, and passes the handle to 'enumHandle'. -- The file will be closed when the 'Iteratee' finishes.-enumFile :: FilePath -> Enumerator E.SomeException B.ByteString IO b+enumFile :: FilePath -> Enumerator B.ByteString IO b enumFile path s = Iteratee io where withHandle = tryStep (IO.openBinaryFile path IO.ReadMode) io = withHandle $ \h -> E.finally@@ -66,7 +66,7 @@ -- -- The handle should be opened with no encoding, and in 'IO.WriteMode' or -- 'IO.ReadWriteMode'.-iterHandle :: IO.Handle -> Iteratee E.SomeException B.ByteString IO ()+iterHandle :: IO.Handle -> Iteratee B.ByteString IO () iterHandle h = continue step where step EOF = yield () EOF step (Chunks []) = continue step
hs/Data/Enumerator/Text.hs view
@@ -52,7 +52,7 @@ -- -- The handle should be opened with an appropriate text encoding, and -- in 'IO.ReadMode' or 'IO.ReadWriteMode'.-enumHandle :: IO.Handle -> Enumerator E.SomeException T.Text IO b+enumHandle :: IO.Handle -> Enumerator T.Text IO b enumHandle h = Iteratee . loop where loop (Continue k) = withText $ \maybeText -> case maybeText of Nothing -> return $ Continue k@@ -66,7 +66,7 @@ else E.throwIO err) -- | Opens a file path in text mode, and passes the handle to 'enumHandle'. -- The file will be closed when the 'Iteratee' finishes.-enumFile :: FilePath -> Enumerator E.SomeException T.Text IO b+enumFile :: FilePath -> Enumerator T.Text IO b enumFile path s = Iteratee io where withHandle = tryStep (IO.openFile path IO.ReadMode) io = withHandle $ \h -> E.finally@@ -78,7 +78,7 @@ -- -- The handle should be opened with an appropriate text encoding, and -- in 'IO.WriteMode' or 'IO.ReadWriteMode'.-iterHandle :: IO.Handle -> Iteratee E.SomeException T.Text IO ()+iterHandle :: IO.Handle -> Iteratee T.Text IO () iterHandle h = continue step where step EOF = yield () EOF step (Chunks []) = continue step@@ -94,7 +94,7 @@ instance Show Codec where showsPrec d c = showParen (d > 10) $ showString "Codec " . shows (codecName c)-encode :: Monad m => Codec -> Enumeratee E.SomeException T.Text B.ByteString m b+encode :: Monad m => Codec -> Enumeratee T.Text B.ByteString m b encode codec = loop where loop = checkDone $ continue . step step k EOF = yield (Continue k) EOF@@ -102,7 +102,7 @@ step k (Chunks xs) = case codecEncode codec xs of Left err -> throwError err Right byteChunks -> k (Chunks byteChunks) >>== loop-decode :: Monad m => Codec -> Enumeratee E.SomeException B.ByteString T.Text m b+decode :: Monad m => Codec -> Enumeratee B.ByteString T.Text m b decode codec = loop B.empty where dec = codecDecode codec
hs/Data/Enumerator/Util.hs view
@@ -2,9 +2,7 @@ import Data.Enumerator import qualified Control.Exception as E -tryStep :: IO t- -> (t -> IO (Step E.SomeException a IO b))- -> IO (Step E.SomeException a IO b)+tryStep :: IO t -> (t -> IO (Step a IO b)) -> IO (Step a IO b) tryStep get io = do tried <- E.try get case tried of