foldl 1.0.2 → 1.0.3
raw patch · 2 files changed
+71/−27 lines, 2 filesdep +transformersdep ~text
Dependencies added: transformers
Dependency ranges changed: text
Files
- foldl.cabal +7/−6
- src/Control/Foldl.hs +64/−21
foldl.cabal view
@@ -1,5 +1,5 @@ Name: foldl-Version: 1.0.2+Version: 1.0.3 Cabal-Version: >=1.8.0.2 Build-Type: Simple License: BSD3@@ -21,11 +21,12 @@ Library HS-Source-Dirs: src Build-Depends:- base >= 4 && < 5 ,- bytestring >= 0.9.2.1 && < 0.11,- primitive < 0.6 ,- text >= 0.11.2.0 && < 1.1 ,- vector >= 0.7 && < 0.11+ base >= 4 && < 5 ,+ bytestring >= 0.9.2.1 && < 0.11,+ primitive < 0.6 ,+ text >= 0.11.2.0 && < 1.2 ,+ transformers >= 0.2.0.0 && < 0.4 ,+ vector >= 0.7 && < 0.11 Exposed-Modules: Control.Foldl, Control.Foldl.ByteString,
src/Control/Foldl.hs view
@@ -36,6 +36,7 @@ -- * Folding , fold , foldM+ , scan -- * Folds , mconcat@@ -71,7 +72,10 @@ -- $utilities , purely , impurely+ , generalize+ , simplify , premap+ , premapM -- * Re-exports -- $reexports@@ -85,6 +89,7 @@ import Control.Monad.Primitive (PrimMonad) import Data.Foldable (Foldable) import qualified Data.Foldable as F+import Data.Functor.Identity (Identity, runIdentity) import Data.Monoid (Monoid(mempty, mappend)) import Data.Vector.Generic (Vector) import qualified Data.Vector.Generic as V@@ -139,7 +144,7 @@ -- | Like 'Fold', but monadic data FoldM m a b = forall x . FoldM (x -> a -> m x) (m x) (x -> m b) -instance (Monad m) => Functor (FoldM m a) where+instance Monad m => Functor (FoldM m a) where fmap f (FoldM step start done) = FoldM step start done' where done' x = do@@ -147,7 +152,7 @@ return $! f b {-# INLINABLE fmap #-} -instance (Monad m) => Applicative (FoldM m a) where+instance Monad m => Applicative (FoldM m a) where pure b = FoldM (\() _ -> return ()) (return ()) (\() -> return b) {-# INLINABLE pure #-} (FoldM stepL beginL doneL) <*> (FoldM stepR beginR doneR) =@@ -173,10 +178,10 @@ {-# INLINABLE mappend #-} -- | Apply a strict left 'Fold' to a 'Foldable' container-fold :: (Foldable f) => Fold a b -> f a -> b-fold (Fold step begin done) as = F.foldr step' done as begin+fold :: Foldable f => Fold a b -> f a -> b+fold (Fold step begin done) as = F.foldr cons done as begin where- step' x k z = k $! step z x+ cons a k x = k $! step x a {-# INLINE fold #-} -- | Like 'fold', but monadic@@ -190,13 +195,21 @@ k $! x' {-# INLINE foldM #-} +-- | Convert a strict left 'Fold' into a scan+scan :: Fold a b -> [a] -> [b]+scan (Fold step begin done) as = foldr cons nil as begin+ where+ nil x = done x:[]+ cons a k x = done x:(k $! step x a)+{-# INLINE scan #-}+ -- | Fold all values within a container using 'mappend' and 'mempty'-mconcat :: (Monoid a) => Fold a a+mconcat :: Monoid a => Fold a a mconcat = Fold mappend mempty id {-# INLINABLE mconcat #-} -- | Convert a \"@foldMap@\" to a 'Fold'-foldMap :: (Monoid w) => (a -> w) -> (w -> b) -> Fold a b+foldMap :: Monoid w => (a -> w) -> (w -> b) -> Fold a b foldMap to from = Fold (\x a -> mappend x (to a)) mempty from {-# INLINABLE foldMap #-} @@ -258,17 +271,17 @@ {-# INLINABLE any #-} -- | Computes the sum of all elements-sum :: (Num a) => Fold a a+sum :: Num a => Fold a a sum = Fold (+) 0 id {-# INLINABLE sum #-} -- | Computes the product all elements-product :: (Num a) => Fold a a+product :: Num a => Fold a a product = Fold (*) 1 id {-# INLINABLE product #-} -- | Computes the maximum element-maximum :: (Ord a) => Fold a (Maybe a)+maximum :: Ord a => Fold a (Maybe a) maximum = Fold step Nothing' lazy where step x a = Just' (case x of@@ -277,7 +290,7 @@ {-# INLINABLE maximum #-} -- | Computes the minimum element-minimum :: (Ord a) => Fold a (Maybe a)+minimum :: Ord a => Fold a (Maybe a) minimum = Fold step Nothing' lazy where step x a = Just' (case x of@@ -288,14 +301,14 @@ {-| @(elem a)@ returns 'True' if the container has an element equal to @a@, 'False' otherwise -}-elem :: (Eq a) => a -> Fold a Bool+elem :: Eq a => a -> Fold a Bool elem a = any (a ==) {-# INLINABLE elem #-} {-| @(notElem a)@ returns 'False' if the container has an element equal to @a@, 'True' otherwise -}-notElem :: (Eq a) => a -> Fold a Bool+notElem :: Eq a => a -> Fold a Bool notElem a = all (a /=) {-# INLINABLE notElem #-} @@ -320,7 +333,7 @@ {-| @(elemIndex a)@ returns the index of the first element that equals @a@, or 'Nothing' if no element matches -}-elemIndex :: (Eq a) => a -> Fold a (Maybe Int)+elemIndex :: Eq a => a -> Fold a (Maybe Int) elemIndex a = findIndex (a ==) {-# INLINABLE elemIndex #-} @@ -339,12 +352,12 @@ {-# INLINABLE findIndex #-} -- | Like 'length', except with a more general 'Num' return value-genericLength :: (Num b) => Fold a b+genericLength :: Num b => Fold a b genericLength = Fold (\n _ -> n + 1) 0 id {-# INLINABLE genericLength #-} -- | Like 'index', except with a more general 'Integral' argument-genericIndex :: (Integral i) => i -> Fold a (Maybe a)+genericIndex :: Integral i => i -> Fold a (Maybe a) genericIndex i = Fold step (Left' 0) done where step x a = case x of@@ -394,13 +407,13 @@ @Pipes.Prelude@ with the following type: > foldM-> :: (Monad m)+> :: Monad m > => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m () -> m b @foldM@ is set up so that you can wrap it with 'impurely' to accept a 'FoldM' instead: -> impurely foldM :: (Monad m) => FoldM m a b -> Producer a m () -> m b+> impurely foldM :: Monad m => FoldM m a b -> Producer a m () -> m b -} -- | Upgrade a fold to accept the 'Fold' type@@ -410,21 +423,51 @@ -- | Upgrade a monadic fold to accept the 'FoldM' type impurely- :: (Monad m)+ :: Monad m => (forall x . (x -> a -> m x) -> m x -> (x -> m b) -> r) -> FoldM m a b -> r impurely f (FoldM step begin done) = f step begin done {-# INLINABLE impurely #-} +-- | Generalize a `Fold` to a `FoldM`+generalize :: Monad m => Fold a b -> FoldM m a b+generalize (Fold step begin done) = FoldM step' begin' done'+ where+ step' x a = return (step x a)+ begin' = return begin+ done' x = return (done x)+{-# INLINABLE generalize #-}++-- | Simplify a pure `FoldM` to a `Fold`+simplify :: FoldM Identity a b -> Fold a b+simplify (FoldM step begin done) = Fold step' begin' done'+ where+ step' x a = runIdentity (step x a)+ begin' = runIdentity begin+ done' x = runIdentity (done x)+{-# INLINABLE simplify #-}+ {-| @(premap f folder)@ returns a new 'Fold' where f is applied at each step- @fold (premap f folder) list@ == @fold folder (map f list)@++> fold (premap f folder) list = fold folder (map f list) -} premap :: (a -> b) -> Fold b r -> Fold a r premap f (Fold step begin done) = Fold step' begin done where- step' x = step x . f+ step' x a = step x (f a) {-# INLINABLE premap #-}++{-| @(premapM f folder)@ returns a new 'FoldM' where f is applied to each input+ element++> foldM (premapM f folder) list = foldM folder (map f list)+-}+premapM :: Monad m => (a -> b) -> FoldM m b r -> FoldM m a r+premapM f (FoldM step begin done) = FoldM step' begin done+ where+ step' x a = step x (f a)+{-# INLINABLE premapM #-} {- $reexports @Control.Monad.Primitive@ re-exports the 'PrimMonad' type class