foldl 1.2.3 → 1.2.4
raw patch · 5 files changed
+119/−90 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Foldl.ByteString: lazy :: Fold ByteString ByteString
+ Control.Foldl.Text: lazy :: Fold Text Text
Files
- README.md +1/−1
- foldl.cabal +1/−1
- src/Control/Foldl.hs +11/−11
- src/Control/Foldl/ByteString.hs +56/−39
- src/Control/Foldl/Text.hs +50/−38
README.md view
@@ -1,4 +1,4 @@-# `foldl` v1.2.3+# `foldl` v1.2.4 Use this `foldl` library when you want to compute multiple folds over a collection in one pass over the data without space leaks.
foldl.cabal view
@@ -1,5 +1,5 @@ Name: foldl-Version: 1.2.3+Version: 1.2.4 Cabal-Version: >=1.8.0.2 Build-Type: Simple License: BSD3
src/Control/Foldl.hs view
@@ -874,18 +874,18 @@ > impurely Pipes.Prelude.foldM > :: Monad m => FoldM m a b -> Producer a m () -> m b - Similarly the @ofoldlUnwrap@ and @ofoldMUnwrap@ functions from the- @monotraversable@ package are written to interoperate with this library:+ Other streaming libraries supporting 'purely' and 'impurely' include @io-streams@ and @streaming@. + So for example we have: -> ofoldlUnwrap-> :: MonoFoldable mono-> => (x -> Element mono -> x) -> x -> (x -> b) -> mono -> b+> purely System.IO.Streams.fold_ +> :: Fold a b -> Streams.InputStream a -> IO b >-> ofoldMUnwrap-> :: (Monad m, MonoFoldable mono)-> => (x -> Element mono -> m x) -> m x -> (x -> m b) -> mono -> m b+> impurely System.IO.Streams.foldM_ +> :: FoldM IO a b -> Streams.InputStream a -> IO b - You can wrap these to accept 'Fold' or 'FoldM', too:+ The @monotraversable@ package makes it convenient to apply a + 'Fold' or 'FoldM' to pure containers that do not allow + a general 'Foldable' instance, like unboxed vectors: > purely ofoldlUnwrap > :: MonoFoldable mono@@ -1066,7 +1066,7 @@ step' = flip (appEndo . getDual . getConst . k (Const . Dual . Endo . flip step)) {-# INLINABLE handles #-} -{- | @{foldOver f folder xs} folds all values from a Lens, Traversal, Prism or Fold with the given folder+{- | @(foldOver f folder xs)@ folds all values from a Lens, Traversal, Prism or Fold with the given folder >>> foldOver (_Just . both) L.sum (Just (2, 3)) 5@@ -1131,7 +1131,7 @@ step' = flip (appEndoM . getDual . getConst . k (Const . Dual . EndoM . flip step)) {-# INLINABLE handlesM #-} -{- | @{foldOverM f folder xs} folds all values from a Lens, Traversal, Prism or Fold monadically with the given folder+{- | @(foldOverM f folder xs)@ folds all values from a Lens, Traversal, Prism or Fold monadically with the given folder > L.foldOverM (folded.f) folder == L.foldM (handlesM f folder)
src/Control/Foldl/ByteString.hs view
@@ -21,6 +21,7 @@ , elemIndex , findIndex , count+ , lazy -- * Re-exports -- $reexports@@ -30,25 +31,30 @@ ) where import Control.Foldl (Fold, FoldM)-import Control.Foldl.Internal (Maybe'(..), lazy, strict, Either'(..), hush)-import qualified Control.Foldl as L+import Control.Foldl.Internal (Maybe'(..), strict, Either'(..), hush) import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy.Internal as Lazy-import qualified Data.ByteString.Unsafe as BU import Data.Word (Word8) import Prelude hiding ( head, last, null, length, any, all, maximum, minimum, elem, notElem ) +import qualified Control.Foldl+import qualified Control.Foldl.Internal+import qualified Data.ByteString+import qualified Data.ByteString.Lazy.Internal+import qualified Data.ByteString.Unsafe+import qualified Data.ByteString.Lazy+ -- | Apply a strict left 'Fold' to a lazy bytestring-fold :: Fold ByteString a -> Lazy.ByteString -> a-fold (L.Fold step begin done) as = done (Lazy.foldlChunks step begin as)+fold :: Fold ByteString a -> Data.ByteString.Lazy.ByteString -> a+fold (Control.Foldl.Fold step begin done) as =+ done (Data.ByteString.Lazy.Internal.foldlChunks step begin as) {-# INLINABLE fold #-} -- | Apply a strict monadic left 'FoldM' to a lazy bytestring-foldM :: Monad m => FoldM m ByteString a -> Lazy.ByteString -> m a-foldM (L.FoldM step begin done) as = do- x <- Lazy.foldlChunks step' begin as+foldM+ :: Monad m => FoldM m ByteString a -> Data.ByteString.Lazy.ByteString -> m a+foldM (Control.Foldl.FoldM step begin done) as = do+ x <- Data.ByteString.Lazy.Internal.foldlChunks step' begin as done x where step' mx bs = do@@ -60,77 +66,81 @@ empty -} head :: Fold ByteString (Maybe Word8)-head = L.Fold step Nothing' lazy+head = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mw8 bs =- if B.null bs+ if Data.ByteString.null bs then mw8 else case mw8 of Just' _ -> mw8- Nothing' -> Just' (BU.unsafeHead bs)+ Nothing' -> Just' (Data.ByteString.Unsafe.unsafeHead bs) {-# INLINABLE head #-} {-| Get the last byte of a byte stream or return 'Nothing' if the byte stream is empty -} last :: Fold ByteString (Maybe Word8)-last = L.Fold step Nothing' lazy+last = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mw8 bs =- if B.null bs+ if Data.ByteString.null bs then mw8- else Just' (B.last bs)+ else Just' (Data.ByteString.last bs) -- TODO: Use `unsafeLast` when Debian Stable Haskell Platform has it {-# INLINABLE last #-} -- | Returns 'True' if the byte stream is empty, 'False' otherwise null :: Fold ByteString Bool-null = L.Fold step True id+null = Control.Foldl.Fold step True id where- step isNull bs = isNull && B.null bs+ step isNull bs = isNull && Data.ByteString.null bs {-# INLINABLE null #-} -- | Return the length of the byte stream in bytes length :: Num n => Fold ByteString n-length = L.Fold (\n bs -> n + fromIntegral (B.length bs)) 0 id+length = Control.Foldl.Fold step 0 id+ where+ step n bs = n + fromIntegral (Data.ByteString.length bs) {-# INLINABLE length #-} {-| @(all predicate)@ returns 'True' if all bytes satisfy the predicate, 'False' otherwise -} all :: (Word8 -> Bool) -> Fold ByteString Bool-all predicate = L.Fold (\b bs -> b && B.all predicate bs) True id+all predicate =+ Control.Foldl.Fold (\b bs -> b && Data.ByteString.all predicate bs) True id {-# INLINABLE all #-} {-| @(any predicate)@ returns 'True' if any byte satisfies the predicate, 'False' otherwise -} any :: (Word8 -> Bool) -> Fold ByteString Bool-any predicate = L.Fold (\b bs -> b || B.any predicate bs) False id+any predicate =+ Control.Foldl.Fold (\b bs -> b || Data.ByteString.any predicate bs) False id {-# INLINABLE any #-} -- | Computes the maximum byte maximum :: Fold ByteString (Maybe Word8)-maximum = L.Fold step Nothing' lazy+maximum = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mw8 bs =- if B.null bs+ if Data.ByteString.null bs then mw8 else Just' (case mw8 of- Nothing' -> B.maximum bs- Just' w8 -> max w8 (B.maximum bs) )+ Nothing' -> Data.ByteString.maximum bs+ Just' w8 -> max w8 (Data.ByteString.maximum bs) ) {-# INLINABLE maximum #-} -- | Computes the minimum byte minimum :: Fold ByteString (Maybe Word8)-minimum = L.Fold step Nothing' lazy+minimum = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mw8 bs =- if B.null bs+ if Data.ByteString.null bs then mw8 else Just' (case mw8 of- Nothing' -> B.minimum bs- Just' w8 -> min w8 (B.minimum bs) )+ Nothing' -> Data.ByteString.minimum bs+ Just' w8 -> min w8 (Data.ByteString.minimum bs) ) {-# INLINABLE minimum #-} {-| @(elem w8)@ returns 'True' if the byte stream has a byte equal to @w8@,@@ -151,10 +161,10 @@ 'Nothing' if no byte satisfies the predicate -} find :: (Word8 -> Bool) -> Fold ByteString (Maybe Word8)-find predicate = L.Fold step Nothing' lazy+find predicate = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mw8 bs = case mw8 of- Nothing' -> strict (B.find predicate bs)+ Nothing' -> strict (Data.ByteString.find predicate bs) Just' _ -> mw8 {-# INLINABLE find #-} @@ -162,13 +172,13 @@ stream has an insufficient number of bytes -} index :: Integral n => n -> Fold ByteString (Maybe Word8)-index i = L.Fold step (Left' (fromIntegral i)) hush+index i = Control.Foldl.Fold step (Left' (fromIntegral i)) hush where step x bs = case x of Left' remainder ->- let len = B.length bs+ let len = Data.ByteString.length bs in if remainder < len- then Right' (BU.unsafeIndex bs remainder)+ then Right' (Data.ByteString.Unsafe.unsafeIndex bs remainder) else Left' (remainder - len) _ -> x {-# INLINABLE index #-}@@ -184,21 +194,28 @@ the predicate, or 'Nothing' if no byte satisfies the predicate -} findIndex :: Num n => (Word8 -> Bool) -> Fold ByteString (Maybe n)-findIndex predicate = L.Fold step (Left' 0) hush+findIndex predicate = Control.Foldl.Fold step (Left' 0) hush where step x bs = case x of- Left' m -> case B.findIndex predicate bs of- Nothing -> Left' (m + fromIntegral (B.length bs))+ Left' m -> case Data.ByteString.findIndex predicate bs of+ Nothing -> Left' (m + fromIntegral (Data.ByteString.length bs)) Just n -> Right' (m + fromIntegral n) _ -> x {-# INLINABLE findIndex #-} -- | @count w8@ returns the number of times @w8@ appears count :: Num n => Word8 -> Fold ByteString n-count w8 = L.Fold step 0 id+count w8 = Control.Foldl.Fold step 0 id where- step n bs = n + fromIntegral (B.count w8 bs)+ step n bs = n + fromIntegral (Data.ByteString.count w8 bs) {-# INLINABLE count #-}++-- | Combine all the strict `ByteString` chunks to build a lazy `ByteString`+lazy :: Fold ByteString Data.ByteString.Lazy.ByteString+lazy = fmap Data.ByteString.Lazy.fromChunks Control.Foldl.list+{-# INLINABLE lazy #-}++-- | {- $reexports
src/Control/Foldl/Text.hs view
@@ -21,6 +21,7 @@ , elemIndex , findIndex , count+ , lazy -- * Re-exports -- $reexports@@ -29,23 +30,26 @@ ) where import Control.Foldl (Fold, FoldM)-import Control.Foldl.Internal (Maybe'(..), lazy, strict, Either'(..), hush)-import qualified Control.Foldl as L+import Control.Foldl.Internal (Maybe'(..), strict, Either'(..), hush) import Data.Text (Text)-import qualified Data.Text as T-import qualified Data.Text.Lazy as Lazy import Prelude hiding ( head, last, null, length, any, all, maximum, minimum, elem, notElem ) +import qualified Control.Foldl+import qualified Control.Foldl.Internal+import qualified Data.Text+import qualified Data.Text.Lazy+ -- | Apply a strict left 'Fold' to lazy text-fold :: Fold Text a -> Lazy.Text -> a-fold (L.Fold step begin done) as = done (Lazy.foldlChunks step begin as)+fold :: Fold Text a -> Data.Text.Lazy.Text -> a+fold (Control.Foldl.Fold step begin done) as =+ done (Data.Text.Lazy.foldlChunks step begin as) {-# INLINABLE fold #-} -- | Apply a strict monadic left 'FoldM' to lazy text-foldM :: Monad m => FoldM m Text a -> Lazy.Text -> m a-foldM (L.FoldM step begin done) as = do- x <- Lazy.foldlChunks step' begin as+foldM :: Monad m => FoldM m Text a -> Data.Text.Lazy.Text -> m a+foldM (Control.Foldl.FoldM step begin done) as = do+ x <- Data.Text.Lazy.foldlChunks step' begin as done x where step' mx bs = do@@ -57,77 +61,80 @@ is empty -} head :: Fold Text (Maybe Char)-head = L.Fold step Nothing' lazy+head = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mc txt =- if T.null txt+ if Data.Text.null txt then mc else case mc of Just' _ -> mc- Nothing' -> Just' (T.head txt)+ Nothing' -> Just' (Data.Text.head txt) {-# INLINABLE head #-} {-| Get the last character of a text stream or return 'Nothing' if the text stream is empty -} last :: Fold Text (Maybe Char)-last = L.Fold step Nothing' lazy+last = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mc txt =- if T.null txt+ if Data.Text.null txt then mc- else Just' (T.last txt)+ else Just' (Data.Text.last txt) -- TODO: Use `unsafeLast` when Debian Stable Haskell Platform has it {-# INLINABLE last #-} -- | Returns 'True' if the text stream is empty, 'False' otherwise null :: Fold Text Bool-null = L.Fold step True id+null = Control.Foldl.Fold step True id where- step isNull txt = isNull && T.null txt + step isNull txt = isNull && Data.Text.null txt {-# INLINABLE null #-} -- | Return the length of the text stream in characters length :: Num n => Fold Text n-length = L.Fold (\n txt -> n + fromIntegral (T.length txt)) 0 id+length =+ Control.Foldl.Fold (\n txt -> n + fromIntegral (Data.Text.length txt)) 0 id {-# INLINABLE length #-} {-| @(all predicate)@ returns 'True' if all characters satisfy the predicate, 'False' otherwise -} all :: (Char -> Bool) -> Fold Text Bool-all predicate = L.Fold (\b txt -> b && T.all predicate txt) True id+all predicate =+ Control.Foldl.Fold (\b txt -> b && Data.Text.all predicate txt) True id {-# INLINABLE all #-} {-| @(any predicate)@ returns 'True' if any character satisfies the predicate, 'False' otherwise -} any :: (Char -> Bool) -> Fold Text Bool-any predicate = L.Fold (\b txt -> b || T.any predicate txt) False id+any predicate =+ Control.Foldl.Fold (\b txt -> b || Data.Text.any predicate txt) False id {-# INLINABLE any #-} -- | Computes the maximum character maximum :: Fold Text (Maybe Char)-maximum = L.Fold step Nothing' lazy+maximum = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mc txt =- if T.null txt+ if Data.Text.null txt then mc else Just' (case mc of- Nothing' -> T.maximum txt- Just' c -> max c (T.maximum txt) )+ Nothing' -> Data.Text.maximum txt+ Just' c -> max c (Data.Text.maximum txt) ) {-# INLINABLE maximum #-} -- | Computes the minimum character minimum :: Fold Text (Maybe Char)-minimum = L.Fold step Nothing' lazy+minimum = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mc txt =- if T.null txt+ if Data.Text.null txt then mc else Just' (case mc of- Nothing' -> T.minimum txt- Just' c -> min c (T.minimum txt) )+ Nothing' -> Data.Text.minimum txt+ Just' c -> min c (Data.Text.minimum txt) ) {-# INLINABLE minimum #-} {-| @(elem c)@ returns 'True' if the text stream has a character equal to @c@,@@ -148,10 +155,10 @@ or 'Nothing' if no character satisfies the predicate -} find :: (Char -> Bool) -> Fold Text (Maybe Char)-find predicate = L.Fold step Nothing' lazy+find predicate = Control.Foldl.Fold step Nothing' Control.Foldl.Internal.lazy where step mc txt = case mc of- Nothing' -> strict (T.find predicate txt)+ Nothing' -> strict (Data.Text.find predicate txt) Just' _ -> mc {-# INLINABLE find #-} @@ -159,13 +166,13 @@ the stream has an insufficient number of characters -} index :: Integral n => n -> Fold Text (Maybe Char)-index i = L.Fold step (Left' (fromIntegral i)) hush+index i = Control.Foldl.Fold step (Left' (fromIntegral i)) hush where step x txt = case x of Left' remainder ->- let len = T.length txt+ let len = Data.Text.length txt in if remainder < len- then Right' (T.index txt remainder)+ then Right' (Data.Text.index txt remainder) else Left' (remainder - len) _ -> x {-# INLINABLE index #-}@@ -182,21 +189,26 @@ predicate -} findIndex :: Num n => (Char -> Bool) -> Fold Text (Maybe n)-findIndex predicate = L.Fold step (Left' 0) hush+findIndex predicate = Control.Foldl.Fold step (Left' 0) hush where step x txt = case x of- Left' m -> case T.findIndex predicate txt of- Nothing -> Left' (m + fromIntegral (T.length txt))+ Left' m -> case Data.Text.findIndex predicate txt of+ Nothing -> Left' (m + fromIntegral (Data.Text.length txt)) Just n -> Right' (m + fromIntegral n) _ -> x {-# INLINABLE findIndex #-} -- | @(count c)@ returns the number of times @c@ appears count :: Num n => Char -> Fold Text n-count c = L.Fold step 0 id+count c = Control.Foldl.Fold step 0 id where- step n txt = n + fromIntegral (T.count (T.singleton c) txt)+ step n txt = n + fromIntegral (Data.Text.count (Data.Text.singleton c) txt) {-# INLINABLE count #-}++-- | Combine all the strict `Text` chunks to build a lazy `Text`+lazy :: Fold Text Data.Text.Lazy.Text+lazy = fmap Data.Text.Lazy.fromChunks Control.Foldl.list+{-# INLINABLE lazy #-} {- $reexports "Control.Foldl" re-exports the 'Fold' type