packages feed

streaming 0.2.2.0 → 0.2.3.0

raw patch · 7 files changed

+486/−499 lines, 7 filesdep +faildep ~basedep ~transformers

Dependencies added: fail

Dependency ranges changed: base, transformers

Files

README.md view
@@ -255,7 +255,7 @@  Rather than wrapping each step in a monadic 'layer', such a layer is put alongside separate 'pure' constructors for a functor 'layer' and a final return value. The maneuver is very friendly to the compiler, but requires a bit of subtlety to protect a sound monad instance. Just such an optimization is adopted internally by the `pipes` library. As in `pipes`, the constructors are here left in an `Internal` module; the main `Streaming` module exporting the type itself and various operations and instances. -I ran a simple [benchmark](https://gist.github.com/michaelt/ee3710c5bab9b7d0892bd552e0eedfd9) (adjusting a [script](https://github.com/jwiegley/streaming-tests) of John Weigly) using a very simple composition of functions:+I ran a simple [benchmark](https://gist.github.com/michaelt/ee3710c5bab9b7d0892bd552e0eedfd9) (adjusting a [script](https://github.com/jwiegley/streaming-tests) of John Wiegley) using a very simple composition of functions:      toList      . filter (\x -> x `mod` 2 == 0) 
changelog.md view
@@ -1,6 +1,23 @@-- ???+- 0.2.3.0+    Add `wrapEffect`. -    Added `nubOrd`, `nubInt`, `nubOrdOn`, `nubIntOn`.+    Compatibility with base 4.13.+    +    Provide a MonadFail instance for Stream.++    Only depend on `semigroups` on old GHCs.++    Add `untilLeft` (counterpart to `untilRight`)++    Add doctests.++    Enable -Wall in cabal file.++    Build with ghc >= 7.10.3.++- 0.2.2.0++    Add `nubOrd`, `nubInt`, `nubOrdOn`, `nubIntOn`.      Fix performance regression in `for`.     
src/Data/Functor/Of.hs view
@@ -1,18 +1,19 @@ {-# LANGUAGE CPP, DeriveDataTypeable, DeriveTraversable, DeriveFoldable,        DeriveGeneric #-}-module Data.Functor.Of where+module Data.Functor.Of (Of(..)) where import Data.Monoid (Monoid (..)) import Data.Semigroup (Semigroup (..)) import Control.Applicative import Data.Traversable (Traversable) import Data.Foldable (Foldable)-#if MIN_VERSION_base(4,8,0) import Data.Bifunctor-#endif import Data.Data-import Data.Typeable-import GHC.Generics (Generic, Generic1)+#if MIN_VERSION_base(4,9,0) import Data.Functor.Classes+import Data.Foldable (Foldable)+import Data.Traversable (Traversable)+#endif+import GHC.Generics (Generic, Generic1)  -- | A left-strict pair; the base functor for streams of individual elements. data Of a b = !a :> b@@ -35,7 +36,7 @@ instance Functor (Of a) where   fmap f (a :> x) = a :> f x   {-#INLINE fmap #-}-  a <$ (b :> x)   = b :> a+  a <$ (b :> _)   = b :> a   {-#INLINE (<$) #-}  #if MIN_VERSION_base(4,8,0)@@ -51,24 +52,31 @@ instance Monoid a => Applicative (Of a) where   pure x = mempty :> x   {-#INLINE pure #-}-  m :> f <*> m' :> x = mappend m m' :> f x+  (m :> f) <*> (m' :> x) = mappend m m' :> f x   {-#INLINE (<*>) #-}-  m :> x *> m' :> y  = mappend m m' :> y+  (m :> _) *> (m' :> y)  = mappend m m' :> y   {-#INLINE (*>) #-}-  m :> x <* m' :> y  = mappend m m' :> x+  (m :> x) <* (m' :> _)  = mappend m m' :> x   {-#INLINE (<*) #-}  instance Monoid a => Monad (Of a) where-  return x = mempty :> x+  return = pure   {-#INLINE return #-}-  m :> x >> m' :> y = mappend m m' :> y+  (m :> _) >> (m' :> y) = mappend m m' :> y   {-#INLINE (>>) #-}-  m :> x >>= f = let m' :> y = f x in mappend m m' :> y+  (m :> x) >>= f = let m' :> y = f x in mappend m m' :> y   {-#INLINE (>>=) #-} +#if MIN_VERSION_base(4,9,0) instance Show a => Show1 (Of a) where   liftShowsPrec = liftShowsPrec2 showsPrec showList +instance Eq a => Eq1 (Of a) where+  liftEq = liftEq2 (==)++instance Ord a => Ord1 (Of a) where+  liftCompare = liftCompare2 compare+ instance Show2 Of where   liftShowsPrec2 spa _sla spb _slb p (a :> b) =     showParen (p > 5) $@@ -76,15 +84,11 @@     showString " :> " .     spb 6 b -instance Eq a => Eq1 (Of a) where-  liftEq = liftEq2 (==)--instance Ord a => Ord1 (Of a) where-  liftCompare = liftCompare2 compare- instance Eq2 Of where-  liftEq2 eq1 eq2 (x :> y) (z :> w) = eq1 x z && eq2 y w+  liftEq2 f g (x :> y) (z :> w) = f x z && g y w  instance Ord2 Of where   liftCompare2 comp1 comp2 (x :> y) (z :> w) =     comp1 x z `mappend` comp2 y w+#endif+
src/Streaming.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE RankNTypes #-} -{-# OPTIONS_GHC -Wall #-} module Streaming    (    -- * An iterable streaming monad transformer@@ -115,10 +114,10 @@     Some of these are quite abstract and pervade any use of the library,     e.g. ->   maps ::    (forall x . f x -> g x)     -> Stream f m r -> Stream g m r->   mapped ::  (forall x . f x -> m (g x)) -> Stream f m r -> Stream g m r->   hoist ::   (forall x . m x -> n x)     -> Stream f m r -> Stream f n r -- from the MFunctor instance->   concats :: Stream (Stream f m) m r -> Stream f m r   +>   maps    :: (forall x . f x -> g x)     -> Stream f m r -> Stream g m r+>   mapped  :: (forall x . f x -> m (g x)) -> Stream f m r -> Stream g m r+>   hoist   :: (forall x . m x -> n x)     -> Stream f m r -> Stream f n r -- from the MFunctor instance+>   concats :: Stream (Stream f m) m r     -> Stream f m r      (assuming here and thoughout that @m@ or @n@ satisfies a @Monad@ constraint, and     @f@ or @g@ a @Functor@ constraint.)@@ -128,12 +127,12 @@ >   chunksOf     :: Int -> Stream f m r -> Stream (Stream f m) m r >   splitsAt     :: Int -> Stream f m r -> Stream f m (Stream f m r) >   zipsWith     :: (forall x y. f x -> g y -> h (x, y))-                 -> Stream f m r -> Stream g m r -> Stream h m r+>                -> Stream f m r -> Stream g m r -> Stream h m r >   zipsWith'    :: (forall x y p. (x -> y -> p) -> f x -> g y -> h p)-                 -> Stream f m r -> Stream g m r -> Stream h m r+>                -> Stream f m r -> Stream g m r -> Stream h m r >   intercalates :: Stream f m () -> Stream (Stream f m) m r -> Stream f m r >   unzips       :: Stream (Compose f g) m r ->  Stream f (Stream g m) r->   separate     :: Stream (Sum f g) m r -> Stream f (Stream g) m r  -- cp. partitionEithers+>   separate     :: Stream (Sum f g) m r -> Stream f (Stream g m) r  -- cp. partitionEithers >   unseparate   :: Stream f (Stream g) m r -> Stream (Sum f g) m r >   groups       :: Stream (Sum f g) m r -> Stream (Sum (Stream f m) (Stream g m)) m r @@ -168,5 +167,3 @@ > concats :: (Monad m, MonadTrans t, Monad (t m)) => Stream (t m) m a -> t m a > concats stream = destroy stream join (join . lift) return -}--
src/Streaming/Internal.hs view
@@ -1,20 +1,17 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}+{-# LANGUAGE BangPatterns          #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE UndecidableInstances  #-} -{-# OPTIONS_GHC -Wall #-} module Streaming.Internal (     -- * The free monad transformer     -- $stream     Stream (..)-  +     -- * Introducing a stream     , unfold     , replicates@@ -28,7 +25,7 @@     , delays     , never     , untilJust-  +     -- * Eliminating a stream     , intercalates     , concats@@ -36,10 +33,10 @@     , iterTM     , destroy     , streamFold-  +     -- * Inspecting a stream wrap by wrap     , inspect-  +     -- * Transforming streams     , maps     , mapsM@@ -52,7 +49,7 @@     , distribute     , groups --    , groupInL-  +     -- *  Splitting streams     , chunksOf     , splitsAt@@ -60,7 +57,7 @@     , cutoff     -- , period     -- , periods-  +     -- * Zipping and unzipping streams     , zipsWith     , zipsWith'@@ -72,10 +69,10 @@     , expand     , expandPost -  +     -- * Assorted Data.Functor.x help     , switch-  +     -- *  For use in implementation     , unexposed     , hoistExposed@@ -83,25 +80,29 @@     , mapsExposed     , mapsMExposed     , destroyExposed-  +    ) where +import Control.Applicative+import Control.Concurrent (threadDelay) import Control.Monad-import Control.Monad.Trans-import Control.Monad.Reader.Class-import Control.Monad.State.Class import Control.Monad.Error.Class-import Control.Applicative-import Data.Function ( on )+import Control.Monad.Fail as Fail import Control.Monad.Morph-import Data.Monoid (Monoid (..))-import Data.Semigroup (Semigroup (..))+import Control.Monad.Reader.Class+import Control.Monad.State.Class+import Control.Monad.Trans import Data.Data (Typeable)-import Prelude hiding (splitAt)+import Data.Function ( on )+import Data.Functor.Classes import Data.Functor.Compose import Data.Functor.Sum-import Data.Functor.Classes-import Control.Concurrent (threadDelay)+import Data.Monoid (Monoid (..))+import Data.Semigroup (Semigroup (..))++-- $setup+-- >>> import Streaming.Prelude as S+ {- $stream      The 'Stream' data type is equivalent to @FreeT@ and can represent any effectful@@ -157,6 +158,8 @@   (<=) = (<=) `on` inspect   (>=) = (>=) `on` inspect +#if MIN_VERSION_base(4,9,0)+ -- We could avoid a Show1 constraint for our Show1 instance by sneakily -- mapping everything to a single known type, but there's really no way -- to do that for Eq1 or Ord1.@@ -165,7 +168,7 @@     where       liftEqExposed (Return x) (Return y) = eq x y       liftEqExposed (Effect m) (Effect n) = liftEq liftEqExposed m n-      liftEqExposed (Step f) (Step g) = liftEq liftEqExposed f g+      liftEqExposed (Step f)   (Step g)   = liftEq liftEqExposed f g       liftEqExposed _ _ = False  instance (Monad m, Functor f, Ord1 m, Ord1 f) => Ord1 (Stream f m) where@@ -173,11 +176,13 @@     where       liftCmpExposed (Return x) (Return y) = cmp x y       liftCmpExposed (Effect m) (Effect n) = liftCompare liftCmpExposed m n-      liftCmpExposed (Step f) (Step g) = liftCompare liftCmpExposed f g+      liftCmpExposed (Step f)   (Step g)   = liftCompare liftCmpExposed f g       liftCmpExposed (Return _) _ = LT       liftCmpExposed _ (Return _) = GT       liftCmpExposed _ _ = error "liftCmpExposed: stream was exposed!" +#endif+ -- We could get a much less scary implementation using Show1, but -- Show1 instances aren't nearly as common as Show instances. --@@ -196,9 +201,11 @@     flip fmap (inspect xs) $ \front ->       SS $ \d -> showParen (d > 10) $         case front of-          Left r ->  showString "Return " . showsPrec 11 r+          Left  r -> showString "Return " . showsPrec 11 r           Right f -> showString "Step "   . showsPrec 11 f) +#if MIN_VERSION_base(4,9,0)+ instance (Monad m, Functor f, Show (m ShowSWrapper), Show (f ShowSWrapper))          => Show1 (Stream f m) where   liftShowsPrec sp sl p xs = showParen (p > 10) $@@ -206,47 +213,62 @@     flip fmap (inspect xs) $ \front ->       SS $ \d -> showParen (d > 10) $         case front of-          Left r ->  showString "Return " . sp 11 r+          Left  r -> showString "Return " . sp 11 r           Right f -> showString "Step "   .                      showsPrec 11 (fmap (SS . (\str i -> liftShowsPrec sp sl i str)) f)) +#endif+ newtype ShowSWrapper = SS (Int -> ShowS) instance Show ShowSWrapper where   showsPrec p (SS s) = s p +-- | Operates covariantly on the stream result, not on its elements:+--+-- @+-- Stream (Of a) m r+--            ^    ^+--            |    `--- This is what `Functor` and `Applicative` use+--            `--- This is what functions like S.map/S.zipWith use+-- @ instance (Functor f, Monad m) => Functor (Stream f m) where   fmap f = loop where     loop stream = case stream of       Return r -> Return (f r)-      Effect m  -> Effect (do {stream' <- m; return (loop stream')})-      Step g -> Step (fmap loop g)+      Effect m -> Effect (do {stream' <- m; return (loop stream')})+      Step   g -> Step (fmap loop g)   {-# INLINABLE fmap #-}   a <$ stream0 = loop stream0 where     loop stream = case stream of       Return _ -> Return a       Effect m -> Effect (do {stream' <- m; return (loop stream')})-      Step f -> Step (fmap loop f)-  {-# INLINABLE (<$) #-}  +      Step   f -> Step (fmap loop f)+  {-# INLINABLE (<$) #-}  instance (Functor f, Monad m) => Monad (Stream f m) where-  return = Return+  return = pure   {-# INLINE return #-}   (>>) = (*>)   {-# INLINE (>>) #-}   -- (>>=) = _bind-  -- {-#INLINE (>>=) #-}+  -- {-# INLINE (>>=) #-}   --   stream >>= f =     loop stream where     loop stream0 = case stream0 of       Step fstr -> Step (fmap loop fstr)-      Effect m   -> Effect (fmap loop m)+      Effect m  -> Effect (fmap loop m)       Return r  -> f r-  {-# INLINABLE (>>=) #-}       +  {-# INLINABLE (>>=) #-} -  fail = lift . fail-  {-#INLINE fail #-}+#if !(MIN_VERSION_base(4,13,0))+  fail = lift . Prelude.fail+  {-# INLINE fail #-}+#endif +instance (Functor f, MonadFail m) => MonadFail (Stream f m) where+  fail = lift . Fail.fail+  {-# INLINE fail #-}  -- _bind --     :: (Functor f, Monad m)@@ -258,7 +280,7 @@ --       Step fstr  -> Step (fmap go fstr) --       Effect m   -> Effect (m >>= \s -> return (go s)) --       Return r  -> f r--- {-#INLINABLE _bind #-}+-- {-# INLINABLE _bind #-} -- -- see https://github.com/Gabriel439/Haskell-Pipes-Library/pull/163 -- for a plan to delay inlining and manage interaction with other operations.@@ -275,12 +297,12 @@ instance (Functor f, Monad m) => Applicative (Stream f m) where   pure = Return   {-# INLINE pure #-}-  streamf <*> streamx = do {f <- streamf; x <- streamx; return (f x)} -  {-# INLINE (<*>) #-}  +  streamf <*> streamx = do {f <- streamf; x <- streamx; return (f x)}+  {-# INLINE (<*>) #-}   stream1 *> stream2 = loop stream1 where     loop stream = case stream of       Return _ -> stream2-      Effect m  -> Effect (fmap loop m)+      Effect m -> Effect (fmap loop m)       Step f   -> Step (fmap loop f)   {-# INLINABLE (*>) #-} @@ -294,21 +316,21 @@ -} instance (Applicative f, Monad m) => Alternative (Stream f m) where   empty = never-  {-#INLINE empty #-}+  {-# INLINE empty #-}    str <|> str' = zipsWith' liftA2 str str'-  {-#INLINE (<|>) #-}+  {-# INLINE (<|>) #-}  instance (Functor f, Monad m, Semigroup w) => Semigroup (Stream f m w) where   a <> b = a >>= \w -> fmap (w <>) b-  {-#INLINE (<>) #-}+  {-# INLINE (<>) #-}  instance (Functor f, Monad m, Monoid w) => Monoid (Stream f m w) where   mempty = return mempty-  {-#INLINE mempty #-}+  {-# INLINE mempty #-} #if !(MIN_VERSION_base(4,11,0))   mappend a b = a >>= \w -> fmap (w `mappend`) b-  {-#INLINE mappend #-}+  {-# INLINE mappend #-} #endif  instance (Applicative f, Monad m) => MonadPlus (Stream f m) where@@ -322,17 +344,17 @@ instance Functor f => MFunctor (Stream f) where   hoist trans = loop  where     loop stream = case stream of-      Return r  -> Return r-      Effect m   -> Effect (trans (fmap loop m))-      Step f    -> Step (fmap loop f)-  {-# INLINABLE hoist #-}  +      Return r -> Return r+      Effect m -> Effect (trans (fmap loop m))+      Step f   -> Step (fmap loop f)+  {-# INLINABLE hoist #-}   instance Functor f => MMonad (Stream f) where   embed phi = loop where     loop stream = case stream of       Return r -> Return r-      Effect  m -> phi m >>= loop+      Effect m -> phi m >>= loop       Step   f -> Step (fmap loop f)   {-# INLINABLE embed #-} @@ -345,7 +367,7 @@   {-# INLINE ask #-}   local f = hoist (local f)   {-# INLINE local #-}- + instance (Functor f, MonadState s m) => MonadState s (Stream f m) where   get = lift get   {-# INLINE get #-}@@ -363,7 +385,7 @@     loop x = case x of       Return r -> Return r       Effect m -> Effect $ fmap loop m `catchError` (return . f)-      Step g -> Step (fmap loop g)+      Step   g -> Step (fmap loop g)   {-# INLINABLE catchError #-}  {-| Map a stream to its church encoding; compare @Data.List.foldr@.@@ -382,7 +404,7 @@   loop stream = case stream of     Return r -> return (done r)     Effect m -> m >>= loop-    Step fs -> return (construct (fmap (theEffect . loop) fs))+    Step fs  -> return (construct (fmap (theEffect . loop) fs)) {-# INLINABLE destroy #-}  @@ -421,11 +443,11 @@   :: (Functor f, Monad m) =>      (r -> b) -> (m b -> b) ->  (f b -> b) -> Stream f m r -> b streamFold done theEffect construct stream  = destroy stream construct theEffect done-{-#INLINE streamFold #-}+{-# INLINE streamFold #-}  {- | Reflect a church-encoded stream; cp. @GHC.Exts.build@ -> streamFold return_ effect_ step_ (streamBuild psi)  = psi return_ effect_ step_+> streamFold return_ effect_ step_ (streamBuild psi) = psi return_ effect_ step_ -} streamBuild   :: (forall b . (r -> b) -> (m b -> b) -> (f b -> b) ->  b) ->  Stream f m r@@ -445,10 +467,10 @@ inspect = loop where   loop stream = case stream of     Return r -> return (Left r)-    Effect m  -> m >>= loop+    Effect m -> m >>= loop     Step fs  -> return (Right fs) {-# INLINABLE inspect #-}-  + {-| Build a @Stream@ by unfolding steps starting from a seed. See also     the specialized 'Streaming.Prelude.unfoldr' in the prelude. @@ -463,9 +485,9 @@ unfold step = loop where   loop s0 = Effect $ do     e <- step s0-    case e of-      Left r -> return (Return r)-      Right fs -> return (Step (fmap loop fs))+    return $ case e of+       Left  r  -> Return r+       Right fs -> Step (fmap loop fs) {-# INLINABLE unfold #-}  @@ -480,9 +502,9 @@      => (forall x . f x -> g x) -> Stream f m r -> Stream g m r maps phi = loop where   loop stream = case stream of-    Return r  -> Return r-    Effect m   -> Effect (fmap loop m)-    Step f    -> Step (phi (fmap loop f))+    Return r -> Return r+    Effect m -> Effect (fmap loop m)+    Step   f -> Step (phi (fmap loop f)) {-# INLINABLE maps #-}  @@ -499,9 +521,9 @@ mapsM :: (Monad m, Functor f) => (forall x . f x -> m (g x)) -> Stream f m r -> Stream g m r mapsM phi = loop where   loop stream = case stream of-    Return r  -> Return r-    Effect m   -> Effect (fmap loop m)-    Step f    -> Effect (fmap Step (phi (fmap loop f)))+    Return r -> Return r+    Effect m -> Effect (fmap loop m)+    Step   f -> Effect (fmap Step (phi (fmap loop f))) {-# INLINABLE mapsM #-}  {- | Map layers of one functor to another with a transformation. Compare@@ -509,8 +531,7 @@  > mapsPost id = id > mapsPost f . mapsPost g = mapsPost (f . g)-> mapsPost f = mapsPost f-+> mapsPost f = maps f       @mapsPost@ is essentially the same as 'maps', but it imposes a 'Functor' constraint on      its target functor rather than its source functor. It should be preferred if 'fmap'@@ -524,7 +545,7 @@   loop stream = case stream of     Return r -> Return r     Effect m -> Effect (fmap loop m)-    Step f -> Step $ fmap loop $ phi f+    Step   f -> Step $ fmap loop $ phi f {-# INLINABLE mapsPost #-}  {- | Map layers of one functor to another with a transformation involving the base monad.@@ -549,7 +570,7 @@   loop stream = case stream of     Return r -> Return r     Effect m -> Effect (fmap loop m)-    Step f -> Effect $ fmap (Step . fmap loop) (phi f)+    Step   f -> Effect $ fmap (Step . fmap loop) (phi f) {-# INLINABLE mapsMPost #-}  {-| Rearrange a succession of layers of the form @Compose m (f x)@.@@ -573,7 +594,7 @@ decompose = loop where   loop stream = case stream of     Return r -> Return r-    Effect m ->  Effect (fmap loop m)+    Effect m -> Effect (fmap loop m)     Step (Compose mstr) -> Effect $ do       str <- mstr       return (Step (fmap loop str))@@ -584,8 +605,8 @@ run :: Monad m => Stream m m r -> m r run = loop where   loop stream = case stream of-    Return r -> return r-    Effect  m -> m >>= loop+    Return r   -> return r+    Effect  m  -> m >>= loop     Step mrest -> mrest >>= loop {-# INLINABLE run #-} @@ -606,16 +627,16 @@ intercalates sep = go0   where     go0 f = case f of-      Return r -> return r-      Effect m -> lift m >>= go0+      Return r  -> return r+      Effect m  -> lift m >>= go0       Step fstr -> do         f' <- fstr         go1 f'     go1 f = case f of-      Return r -> return r-      Effect m     -> lift m >>= go1+      Return r  -> return r+      Effect m  -> lift m >>= go1       Step fstr ->  do-        _ <- sep+        _  <- sep         f' <- fstr         go1 f' {-# INLINABLE intercalates #-}@@ -649,7 +670,7 @@ concats  = loop where   loop stream = case stream of     Return r -> return r-    Effect m  -> lift m >>= loop+    Effect m -> lift m >>= loop     Step fs  -> fs >>= loop {-# INLINE concats #-} @@ -679,11 +700,11 @@ splitsAt :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Stream f m r) splitsAt  = loop  where   loop !n stream-    | n <= 0 = Return stream+    | n <= 0    = Return stream     | otherwise = case stream of-        Return r       -> Return (Return r)-        Effect m        -> Effect (fmap (loop n) m)-        Step fs        -> case n of+        Return r -> Return (Return r)+        Effect m -> Effect (fmap (loop n) m)+        Step fs  -> case n of           0 -> Return (Step fs)           _ -> Step (fmap (loop (n-1)) fs) {-# INLINABLE splitsAt #-}@@ -716,7 +737,7 @@ -} takes :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m () takes n = void . splitsAt n-{-# INLINE takes #-}                      +{-# INLINE takes #-}  {-| Break a stream into substreams each with n functorial layers. @@ -731,7 +752,7 @@     Return r  -> Return r     Effect m  -> Effect (fmap loop m)     Step fs   -> Step (Step (fmap (fmap loop . splitsAt (n0-1)) fs))-{-# INLINABLE chunksOf #-}        +{-# INLINABLE chunksOf #-}  {- | Make it possible to \'run\' the underlying transformed monad. -}@@ -742,19 +763,19 @@     Return r     -> lift (Return r)     Effect tmstr -> hoist lift tmstr >>= loop     Step fstr    -> join (lift (Step (fmap (Return . loop) fstr)))-{-#INLINABLE distribute #-}-  +{-# INLINABLE distribute #-}+ -- | Repeat a functorial layer (a \"command\" or \"instruction\") forever. repeats :: (Monad m, Functor f) => f () -> Stream f m r repeats f = loop where-  loop = Effect (return (Step (fmap (\_ -> loop) f)))+  loop = Effect (return (Step (loop <$ f)))  -- | Repeat an effect containing a functorial layer, command or instruction forever. repeatsM :: (Monad m, Functor f) => m (f ()) -> Stream f m r repeatsM mf = loop where   loop = Effect $ do      f <- mf-     return $ Step $ fmap (\_ -> loop) f+     return $ Step $ loop <$ f  {- | Repeat a functorial layer, command or instruction a fixed number of times. @@ -788,7 +809,7 @@ inspectC :: Monad m => (r -> m a) -> (f (Stream f m r) -> m a) -> Stream f m r -> m a inspectC f g = loop where   loop (Return r) = f r-  loop (Step x) = g x+  loop (Step x)   = g x   loop (Effect m) = m >>= loop {-# INLINE inspectC #-} @@ -798,9 +819,9 @@ hoistExposed :: (Functor m, Functor f) => (forall b. m b -> n b) -> Stream f m a -> Stream f n a hoistExposed trans = loop where   loop stream = case stream of-    Return r  -> Return r-    Effect m   -> Effect (trans (fmap loop m))-    Step f    -> Step (fmap loop f)+    Return r -> Return r+    Effect m -> Effect (trans (fmap loop m))+    Step f   -> Step (fmap loop f) {-# INLINABLE hoistExposed #-}  -- | The same as 'hoistExposed', but with a 'Functor' constraint on@@ -811,7 +832,7 @@   loop stream = case stream of     Return r -> Return r     Effect m -> Effect (fmap loop (trans m))-    Step f -> Step (fmap loop f)+    Step   f -> Step (fmap loop f) {-# INLINABLE hoistExposedPost #-}  {-# DEPRECATED mapsExposed "Use maps instead." #-}@@ -844,7 +865,7 @@ destroyExposed stream0 construct theEffect done = loop stream0 where   loop stream = case stream of     Return r -> done r-    Effect m  -> theEffect (fmap loop m)+    Effect m -> theEffect (fmap loop m)     Step fs  -> construct (fmap loop fs) {-# INLINABLE destroyExposed #-} @@ -858,9 +879,9 @@ unexposed = Effect . loop where   loop stream = case stream of     Return r -> return (Return r)-    Effect  m -> m >>= loop+    Effect m -> m >>= loop     Step   f -> return (Step (fmap (Effect . loop) f))-{-# INLINABLE unexposed #-} +{-# INLINABLE unexposed #-}   {-| Wrap a new layer of a stream. So, e.g.@@ -889,7 +910,7 @@ -} wrap :: (Monad m, Functor f ) => f (Stream f m r) -> Stream f m r wrap = Step-{-#INLINE wrap #-}+{-# INLINE wrap #-}   {- | Wrap an effect that returns a stream@@ -899,7 +920,7 @@ -} effect :: (Monad m, Functor f ) => m (Stream f m r) -> Stream f m r effect = Effect-{-#INLINE effect #-}+{-# INLINE effect #-}   {-| @yields@ is like @lift@ for items in the streamed functor.@@ -916,7 +937,7 @@  yields ::  (Monad m, Functor f) => f r -> Stream f m r yields fr = Step (fmap Return fr)-{-#INLINE yields #-}+{-# INLINE yields #-}  {- Note that if the first stream produces Return, we don't inspect@@ -966,9 +987,9 @@     loop :: Stream f m r -> Stream g m r -> Stream h m r     loop s t = case s of        Return r -> Return r-       Step fs -> case t of+       Step fs  -> case t of          Return r -> Return r-         Step gs -> Step $ phi loop fs gs+         Step gs  -> Step $ phi loop fs gs          Effect n -> Effect $ fmap (loop s) n        Effect m -> Effect $ fmap (flip loop t) m {-# INLINABLE zipsWith' #-}@@ -977,7 +998,7 @@      => Stream f m r -> Stream g m r -> Stream (Compose f g) m r zips = zipsWith' go where   go p fx gy = Compose (fmap (\x -> fmap (\y -> p x y) gy) fx)-{-# INLINE zips #-} +{-# INLINE zips #-}   @@ -998,7 +1019,7 @@   :: (Monad m, Applicative h) =>      Stream h m r -> Stream h m r -> Stream h m r interleaves = zipsWith' liftA2-{-# INLINE interleaves #-} +{-# INLINE interleaves #-}   {-| Swap the order of functors in a sum of functors.@@ -1016,7 +1037,7 @@ -} switch :: Sum f g r -> Sum g f r switch s = case s of InL a -> InR a; InR a -> InL a-{-#INLINE switch #-}+{-# INLINE switch #-}   @@ -1033,13 +1054,13 @@      Now, for example, it is convenient to fold on the left and right values separately: ->>>  S.toList $ S.toList $ separate odd_even+>>> S.toList $ S.toList $ separate odd_even [2,4,6,8,10] :> ([1,3,5,7,9] :> ())      Or we can write them to separate files or whatever: ->>> runResourceT $ S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even+>>> S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even >>> :! cat even.txt 2 4@@ -1070,7 +1091,7 @@   (\x -> case x of InL fss -> wrap fss; InR gss -> effect (yields gss))   (effect . lift)   return-{-#INLINABLE separate #-}+{-# INLINABLE separate #-}   @@ -1080,7 +1101,7 @@   (wrap . InL)   (join . maps InR)   return-{-#INLINABLE unseparate #-}+{-# INLINABLE unseparate #-}  -- | If 'Of' had a @Comonad@ instance, then we'd have --@@ -1093,7 +1114,7 @@        -> Stream f m r -> Stream g (Stream h m) r expand ext = loop where   loop (Return r) = Return r-  loop (Step f) = Effect $ Step $ ext (Return . Step) (fmap loop f)+  loop (Step f)   = Effect $ Step $ ext (Return . Step) (fmap loop f)   loop (Effect m) = Effect $ Effect $ fmap (Return . loop) m {-# INLINABLE expand #-} @@ -1108,7 +1129,7 @@        -> Stream f m r -> Stream g (Stream h m) r expandPost ext = loop where   loop (Return r) = Return r-  loop (Step f) = Effect $ Step $ ext (Return . Step . fmap loop) f+  loop (Step f)   = Effect $ Step $ ext (Return . Step . fmap loop) f   loop (Effect m) = Effect $ Effect $ fmap (Return . loop) m {-# INLINABLE expandPost #-} @@ -1119,7 +1140,7 @@   (\(Compose fgstr) -> Step (fmap (Effect . yields) fgstr))   (Effect . lift)   return-{-#INLINABLE unzips #-}+{-# INLINABLE unzips #-}  {-| Group layers in an alternating stream into adjoining sub-streams     of one type or another.@@ -1156,8 +1177,8 @@       Left r           -> return (return r)       Right (InL fstr) -> return (wrap (InL fstr))       Right (InR gstr) -> wrap (fmap go gstr)-{-#INLINABLE groups #-}-    +{-# INLINABLE groups #-}+ -- groupInL :: (Monad m, Functor f, Functor g) --                      => Stream (Sum f g) m r --                      -> Stream (Sum (Stream f m) g) m r@@ -1249,14 +1270,14 @@ -- The Monad m constraint should really be an Applicative one, -- but we still support old versions of base. never =  let loop = Step $ pure (Effect (return loop)) in loop-{-#INLINABLE never #-}+{-# INLINABLE never #-}   delays :: (MonadIO m, Applicative f) => Double -> Stream f m r delays seconds = loop where   loop = Effect $ liftIO (threadDelay delay) >> return (Step (pure loop))   delay = fromInteger (truncate (1000000 * seconds))-{-#INLINABLE delays #-}+{-# INLINABLE delays #-}  -- {-| Permit streamed actions to proceed unless the clock has run out. --@@ -1275,7 +1296,7 @@ --     loop str --   where --   cutoff = fromInteger (truncate (1000000000 * seconds))--- {-#INLINABLE period #-}+-- {-# INLINABLE period #-} -- -- -- {-| Divide a succession of phases according to a specified time interval. If time runs out@@ -1339,11 +1360,11 @@ untilJust act = loop where   loop = Effect $ do     m <- act-    case m of-      Nothing -> return $ Step $ pure loop-      Just a -> return $ Return a-    -    +    return $ case m of+      Nothing -> Step $ pure loop+      Just a  -> Return a++ cutoff :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Maybe r) cutoff = loop where   loop 0 _ = return Nothing@@ -1351,4 +1372,4 @@       e <- lift $ inspect str       case e of         Left r -> return (Just r)-        Right (frest) -> Step $ fmap (loop (n-1)) frest+        Right frest -> Step $ fmap (loop (n-1)) frest
src/Streaming/Prelude.hs view
@@ -1,4 +1,4 @@-{-| This names exported by this module are closely modeled on those in @Prelude@ and @Data.List@,+{-| The names exported by this module are closely modeled on those in @Prelude@ and @Data.List@,     but also on     <http://hackage.haskell.org/package/pipes-4.1.9/docs/Pipes-Prelude.html Pipes.Prelude>,     <http://hackage.haskell.org/package/pipes-group-1.0.3/docs/Pipes-Group.html Pipes.Group>@@ -8,7 +8,7 @@     articulated in the latter two modules. Because we dispense with piping and     conduiting, the distinction between all of these modules collapses. Some things are     lost but much is gained: on the one hand, everything comes much closer to ordinary-    beginning Haskell programming and, on the other, acquires the plasticity of programming +    beginning Haskell programming and, on the other, acquires the plasticity of programming     directly with a general free monad type. The leading type, @Stream (Of a) m r@ is chosen to permit an api     that is as close as possible to that of @Data.List@ and the @Prelude@. @@ -47,17 +47,11 @@ > -------------------------------------------------------------------------------------------------------------------- > -}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BangPatterns        #-}+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE RankNTypes          #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}--{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE TypeFamilies        #-}  module Streaming.Prelude (     -- * Types@@ -70,21 +64,22 @@     , stdinLn     , readLn     , fromHandle-    , readFile +    , readFile     , iterate     , iterateM     , repeat     , repeatM     , replicate+    , untilLeft     , untilRight     , cycle     , replicateM     , enumFrom     , enumFromThen     , unfoldr-      +     -- * Consuming streams of elements     -- $consumers     , stdoutLn@@ -92,7 +87,7 @@     , mapM_     , print     , toHandle-    , writeFile +    , writeFile     , effects     , erase     , drained@@ -138,8 +133,8 @@     , read     , show     , cons-    , slidingWindow    -+    , slidingWindow+    , wrapEffect      -- * Splitting and inspecting streams of elements     , next@@ -235,7 +230,7 @@     , merge     , mergeOn     , mergeBy-    +     -- * Maybes     -- $maybes     , catMaybes@@ -256,19 +251,31 @@     -- * Basic Type     , Stream   ) where+ import Streaming.Internal +import Control.Applicative (Applicative (..))+import Control.Concurrent (threadDelay)+import Control.Exception (throwIO, try) import Control.Monad hiding (filterM, mapM, mapM_, foldM, foldM_, replicateM, sequence)-import Data.Functor.Identity-import Data.Functor.Sum import Control.Monad.Trans-import Control.Applicative (Applicative (..)) import Data.Functor (Functor (..), (<$))--import qualified Prelude as Prelude+import Data.Functor.Compose+import Data.Functor.Identity+import Data.Functor.Of+import Data.Functor.Sum+import Data.Monoid (Monoid (mappend, mempty))+import Data.Ord (Ordering (..), comparing)+import Foreign.C.Error (Errno(Errno), ePIPE)+import Text.Read (readMaybe) import qualified Data.Foldable as Foldable+import qualified Data.IntSet as IntSet import qualified Data.Sequence as Seq-import Text.Read (readMaybe)+import qualified Data.Set as Set+import qualified GHC.IO.Exception as G+import qualified Prelude+import qualified System.IO as IO+ import Prelude hiding (map, mapM, mapM_, filter, drop, dropWhile, take, mconcat                       , sum, product, iterate, repeat, cycle, replicate, splitAt                       , takeWhile, enumFrom, enumFromTo, enumFromThen, length@@ -277,24 +284,26 @@                       , minimum, maximum, elem, notElem, all, any, head                       , last, foldMap) -import qualified GHC.IO.Exception as G-import qualified System.IO as IO-import Foreign.C.Error (Errno(Errno), ePIPE)-import Control.Exception (throwIO, try)-import Data.Monoid (Monoid (mappend, mempty))-import Control.Concurrent (threadDelay)-import Data.Functor.Compose-import Data.Functor.Of-import qualified Data.Set as Set-import qualified Data.IntSet as IntSet-import Data.Ord (Ordering (..), comparing) ++-- $setup+-- >>> import Control.Applicative+-- >>> import qualified Control.Foldl as L+-- >>> import Data.Bifunctor (first)+-- >>> import Data.Function ((&))+-- >>> import Data.IORef+-- >>> import Data.Vector (Vector)+-- >>> import qualified Streaming.Prelude as S+-- >>> import qualified System.IO+-- >>> import Text.Read (readEither)++ -- instance (Eq a) => Eq1 (Of a) where eq1 = (==) -- instance (Ord a) => Ord1 (Of a) where compare1 = compare -- instance (Read a) => Read1 (Of a) where readsPrec1 = readsPrec -- instance (Show a) => Show1 (Of a) where showsPrec1 = showsPrec -{-| Note that 'lazily', 'strictly', 'fst'', and 'mapOf' are all so-called /natural transformations/ on the primitive @Of a@ functor+{-| Note that 'lazily', 'strictly', 'fst'', and 'mapOf' are all so-called /natural transformations/ on the primitive @Of a@ functor.     If we write  >  type f ~~> g = forall x . f x -> g x@@ -319,7 +328,7 @@   This rests on recognizing that @mapOf@ is a natural transformation; note though   that it results in such a transformation as well: ->  S.map :: (a -> b) -> Stream (Of a) m ~> Stream (Of b) m+>  S.map :: (a -> b) -> Stream (Of a) m ~~> Stream (Of b) m    Thus we can @maps@ it in turn. @@ -355,10 +364,10 @@  fst' :: Of a b -> a fst' (a :> _) = a-{-#INLINE fst' #-}+{-# INLINE fst' #-} snd' :: Of a b -> b snd' (_ :> b) = b-{-#INLINE snd' #-}+{-# INLINE snd' #-}  {-| Map a function over the first element of an @Of@ pair @@ -379,18 +388,18 @@  -}  mapOf :: (a -> b) -> Of a r -> Of b r-mapOf f (a:> b) = (f a :> b)-{-#INLINE mapOf #-}+mapOf f (a :> b) = f a :> b+{-# INLINE mapOf #-}  {-| A lens into the first element of a left-strict pair -} _first :: Functor f => (a -> f a') -> Of a b -> f (Of a' b)-_first afb (a:>b) = fmap (\c -> (c:>b)) (afb a)+_first afb (a :> b) = fmap (\c -> c :> b) (afb a) {-# INLINE _first #-}  {-| A lens into the second element of a left-strict pair -} _second :: Functor f => (b -> f b') -> Of a b -> f (Of a b')-_second afb (a:>b) = fmap (\c -> (a:>c)) (afb b)-{-#INLINABLE _second #-}+_second afb (a :> b) = fmap (\c -> a :> c) (afb b)+{-# INLINABLE _second #-}  all :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m (Of Bool r) all thus = loop True where@@ -402,7 +411,7 @@       else do         r <- effects rest         return (False :> r)-{-#INLINABLE all #-}+{-# INLINABLE all #-}  all_ :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m Bool all_ thus = loop True where@@ -412,7 +421,7 @@     Step (a :> rest) -> if thus a       then loop True rest       else return False-{-#INLINABLE all_ #-}+{-# INLINABLE all_ #-}   any :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m (Of Bool r)@@ -425,7 +434,7 @@         r <- effects rest         return (True :> r)       else loop False rest-{-#INLINABLE any #-}+{-# INLINABLE any #-}  any_ :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m Bool any_ thus = loop False where@@ -435,7 +444,7 @@     Step (a :> rest) -> if thus a       then return True       else loop False rest-{-#INLINABLE any_ #-}+{-# INLINABLE any_ #-}  {-| Break a sequence upon meeting element falls under a predicate,     keeping it and the rest of the stream as the return value.@@ -454,8 +463,8 @@ break thePred = loop where   loop str = case str of     Return r         -> Return (Return r)-    Effect m          -> Effect $ fmap loop m-    Step (a :> rest) -> if (thePred a)+    Effect m         -> Effect $ fmap loop m+    Step (a :> rest) -> if thePred a       then Return (Step (a :> rest))       else Step (a :> loop rest) {-# INLINABLE break #-}@@ -465,7 +474,7 @@    and the element that breaks it will be put after the break.    This function is easiest to use with 'Control.Foldl.purely' ->>>  rest <- each [1..10] & L.purely S.breakWhen L.sum (>10) & S.print+>>> rest <- each [1..10] & L.purely S.breakWhen L.sum (>10) & S.print 1 2 3@@ -486,7 +495,7 @@         Return r -> return (return r)         Effect mn  -> Effect $ fmap (loop0 x) mn         Step (a :> rest) -> loop a (step x a) rest-    loop a !x stream = do+    loop a !x stream =       if thePred (done x)         then return (yield a >> stream)         else case stream of@@ -497,17 +506,17 @@             loop a' (step x a') rest {-# INLINABLE breakWhen #-} --- -- Break during periods where the predicate is not satisfied, grouping the periods when it is.------ >>> S.print $ mapped S.toList $ S.breaks not $ S.each [False,True,True,False,True,True,False]--- [True,True]--- [True,True]--- >>> S.print $ mapped S.toList $ S.breaks id $ S.each [False,True,True,False,True,True,False]--- [False]--- [False]--- [False]------ -}+{-| Break during periods where the predicate is not satisfied, grouping the periods when it is.++>>> S.print $ mapped S.toList $ S.breaks not $ S.each [False,True,True,False,True,True,False]+[True,True]+[True,True]+>>> S.print $ mapped S.toList $ S.breaks id $ S.each [False,True,True,False,True,True,False]+[False]+[False]+[False]++-} breaks   :: Monad m =>      (a -> Bool) -> Stream (Of a) m r -> Stream (Stream (Of a) m) m r@@ -520,9 +529,10 @@        if not (thus a)           then Step $ fmap loop (yield a >> break thus p')           else loop p'-{-#INLINABLE breaks #-}+{-# INLINABLE breaks #-} -{-| Apply an action to all values, re-yielding each+{-| Apply an action to all values, re-yielding each.+    The return value (@y@) of the function is ignored.  >>> S.product $ S.chain Prelude.print $ S.each [1..5] 1@@ -531,15 +541,17 @@ 4 5 120 :> ()++See also 'mapM' for a variant of this which uses the return value of the function to transorm the values in the stream. -} -chain :: Monad m => (a -> m ()) -> Stream (Of a) m r -> Stream (Of a) m r+chain :: Monad m => (a -> m y) -> Stream (Of a) m r -> Stream (Of a) m r chain f = loop where   loop str = case str of     Return r -> return r     Effect mn  -> Effect (fmap loop mn)     Step (a :> rest) -> Effect $ do-      f a+      _ <- f a       return (Step (a :> loop rest)) {-# INLINABLE chain #-} @@ -554,7 +566,7 @@ 'z'      Note that it also has the effect of 'Data.Maybe.catMaybes', 'Data.Either.rights'-    'map snd' and such-like operations.+    @map snd@ and such-like operations.  >>> S.print $ S.concat $ S.each [Just 1, Nothing, Just 2] 1@@ -616,7 +628,7 @@  cycle :: (Monad m, Functor f) => Stream f m r -> Stream f m s cycle str = loop where loop = str >> loop-{-#INLINABLE cycle #-}+{-# INLINABLE cycle #-}   {-| Interpolate a delay of n seconds between yields.@@ -632,7 +644,7 @@         yield a         liftIO $ threadDelay pico         loop rest-{-#INLINABLE delay #-}+{-# INLINABLE delay #-}   @@ -661,14 +673,14 @@ -} drained :: (Monad m, Monad (t m), MonadTrans t) => t m (Stream (Of a) m r) -> t m r drained tms = tms >>= lift . effects-{-#INLINE drained #-}+{-# INLINE drained #-}  -- --------------- -- drop -- --------------- {-|  Ignore the first n elements of a stream, but carry out the actions ->>> S.toList $ S.drop 2 $  S.replicateM 5 getLine+>>> S.toList $ S.drop 2 $ S.replicateM 5 getLine a<Enter> b<Enter> c<Enter>@@ -681,9 +693,6 @@  >>> S.toList $ concats $ maps (S.drop 4) $ chunksOf 5 $ each [1..20] [5,10,15,20] :> ()---   -}  drop :: (Monad m) => Int -> Stream (Of a) m r -> Stream (Of a) m r@@ -767,8 +776,21 @@     Return r         -> return r     Effect m         -> m >>= loop     Step (_ :> rest) -> loop rest-{-#INLINABLE effects #-}+{-# INLINABLE effects #-} +{-| Before evaluating the monadic action returning the next step in the 'Stream', @wrapEffect@+    extracts the value in a monadic computation @m a@ and passes it to a computation @a -> m y@.++-}+wrapEffect :: (Monad m, Functor f) => m a -> (a -> m y) -> Stream f m r -> Stream f m r+wrapEffect m f = loop where+  loop stream = do+    x <- lift m+    step <- lift $ inspect stream+    _ <- lift $ f x+    either pure loop' step+  loop' stream = wrap (fmap loop stream)+ {-| Exhaust a stream remembering only whether @a@ was an element.  -}@@ -783,7 +805,7 @@       if a == a'         then fmap (True :>) (effects rest)         else loop False rest-{-#INLINABLE elem #-}+{-# INLINABLE elem #-}  elem_ :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m Bool elem_ a' = loop False where@@ -795,7 +817,7 @@       if a == a'         then return True         else loop False rest-{-#INLINABLE elem_ #-}+{-# INLINABLE elem_ #-}  -- ----- -- enumFrom@@ -803,8 +825,8 @@  {-| An infinite stream of enumerable values, starting from a given value.     It is the same as @S.iterate succ@.-   Because their return type is polymorphic, @enumFrom@ and @enumFromThen@-   (and @iterate@ are useful for example with @zip@+   Because their return type is polymorphic, @enumFrom@, @enumFromThen@+   and @iterate@ are useful for example with @zip@    and @zipWith@, which require the same return type in the zipped streams.    With @each [1..]@ the following bit of connect-and-resume would be impossible: @@ -870,7 +892,7 @@       else loop as {-# INLINE filter #-}  -- ~ 10% faster than INLINABLE in simple bench -                         + -- --------------- -- filterM -- ---------------@@ -913,10 +935,10 @@ {- $folds     Use these to fold the elements of a 'Stream'. ->>> S.fold_ (+) 0 id $ S.each [1..0]-50+>>> S.fold_ (+) 0 id $ S.each [1..10]+55 -    The general folds 'fold', fold_', 'foldM' and 'foldM_' are arranged+    The general folds 'fold', 'fold_', 'foldM' and 'foldM_' are arranged     for use with @Control.Foldl@ 'Control.Foldl.purely' and 'Control.Foldl.impurely'  >>> L.purely fold_ L.sum $ each [1..10]@@ -924,8 +946,8 @@ >>> L.purely fold_ (liftA3 (,,) L.sum L.product L.list) $ each [1..10] (55,3628800,[1,2,3,4,5,6,7,8,9,10]) -    All functions marked with an underscore omit-    (e.g. @fold_@, @sum_@) the stream's return value in a left-strict pair.+    All functions marked with an underscore+    (e.g. @fold_@, @sum_@) omit the stream's return value in a left-strict pair.     They are good for exiting streaming completely,     but when you are, e.g. @mapped@-ing over a @Stream (Stream (Of a) m) m r@,     which is to be compared with @[[a]]@. Specializing, we have e.g.@@ -962,7 +984,7 @@ -} fold_ :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> m b fold_ step begin done = fmap (\(a :> _) -> a) . fold step begin done-{-#INLINE fold_ #-}+{-# INLINE fold_ #-}  {-| Strict fold of a 'Stream' of elements that preserves the return value.     The third parameter will often be 'id' where a fold is written by hand:@@ -1006,7 +1028,7 @@ {-# INLINE fold #-}  -{-| Strict, monadic fold of the elements of a 'Stream (Of a)'+{-| Strict, monadic fold of the elements of a @Stream (Of a)@  > Control.Foldl.impurely foldM :: Monad m => FoldM a b -> Stream (Of a) m () -> m b -}@@ -1014,16 +1036,16 @@     :: Monad m     => (x -> a -> m x) -> m x -> (x -> m b) -> Stream (Of a) m r -> m b foldM_ step begin done = fmap (\(a :> _) -> a) . foldM step begin done-{-#INLINE foldM_ #-}+{-# INLINE foldM_ #-} -{-| Strict, monadic fold of the elements of a 'Stream (Of a)'+{-| Strict, monadic fold of the elements of a @Stream (Of a)@  > Control.Foldl.impurely foldM' :: Monad m => FoldM a b -> Stream (Of a) m r -> m (b, r)     Thus to accumulate the elements of a stream as a vector, together with a random    element we might write: ->>>  L.impurely S.foldM (liftA2 (,) L.vector L.random) $ each [1..10::Int] :: IO (Of (U.Vector Int,Maybe Int) ())+>>> L.impurely S.foldM (liftA2 (,) L.vectorM L.random) $ each [1..10::Int] :: IO (Of (Vector Int, Maybe Int) ()) ([1,2,3,4,5,6,7,8,9,10],Just 9) :> ()  -}@@ -1055,7 +1077,7 @@ --       b <- done x' --       return (b :> r) --   where seq = Prelude.seq--- {-#INLINE foldM #-}+-- {-# INLINE foldM #-}  {-| A natural right fold for consuming a stream of elements.     See also the more general 'iterTM' in the 'Streaming' module@@ -1096,11 +1118,11 @@ -- | @for@ replaces each element of a stream with an associated stream. Note that the -- associated stream may layer any functor. for :: (Monad m, Functor f) => Stream (Of a) m r -> (a -> Stream f m x) -> Stream f m r-for str0 act = loop str0 where+for str0 f = loop str0 where   loop str = case str of     Return r         -> Return r-    Effect m          -> Effect $ fmap loop m-    Step (a :> rest) -> act a *> loop rest+    Effect m         -> Effect $ fmap loop m+    Step (a :> as) -> f a *> loop as {-# INLINABLE for #-}  -- -| Group layers of any functor by comparisons on a preliminary annotation@@ -1166,7 +1188,7 @@ -} group :: (Monad m, Eq a) => Stream (Of a) m r -> Stream (Stream (Of a) m) m r group = groupBy (==)-{-#INLINE group #-}+{-# INLINE group #-}   head :: Monad m => Stream (Of a) m r -> m (Of (Maybe a) r)@@ -1174,15 +1196,26 @@   Return r            -> return (Nothing :> r)   Effect m            -> m >>= head   Step (a :> rest)    -> effects rest >>= \r -> return (Just a :> r)-{-#INLINABLE head #-}+{-# INLINABLE head #-}  head_ :: Monad m => Stream (Of a) m r -> m (Maybe a) head_ str = case str of   Return _ -> return Nothing   Effect m -> m >>= head_   Step (a :> _) -> return (Just a)-{-#INLINABLE head_ #-}+{-# INLINABLE head_ #-} ++{-| Intersperse given value between each element of the stream.++>>> S.print $ S.intersperse 0 $ each [1,2,3]+1+0+2+0+3++-} intersperse :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r intersperse x str = case str of     Return r -> Return r@@ -1193,7 +1226,7 @@     Return r -> Step (a :> Return r)     Effect m -> Effect (fmap (loop a) m)     Step (b :> rest) -> Step (a :> Step (x :> loop b rest))-{-#INLINABLE intersperse #-}+{-# INLINABLE intersperse #-}   @@ -1230,7 +1263,7 @@       Just_ a  -> return (Just a :> r)     Effect m            -> m >>= loop mb     Step (a :> rest)  -> loop (Just_ a) rest-{-#INLINABLE last #-}+{-# INLINABLE last #-}   @@ -1242,7 +1275,7 @@       Just_ a  -> return (Just a)     Effect m -> m >>= loop mb     Step (a :> rest) -> loop (Just_ a) rest-{-#INLINABLE last_ #-}+{-# INLINABLE last_ #-}   -- ---------------@@ -1251,13 +1284,13 @@  {-| Run a stream, remembering only its length: ->>> S.length $ S.each [1..10]+>>> runIdentity $ S.length_ (S.each [1..10] :: Stream (Of Int) Identity ()) 10  -} length_ :: Monad m => Stream (Of a) m r -> m Int length_ = fold_ (\n _ -> n + 1) 0 id-{-#INLINE length_#-}+{-# INLINE length_ #-}  {-| Run a stream, keeping its length and its return value. @@ -1271,7 +1304,7 @@  length :: Monad m => Stream (Of a) m r -> m (Of Int r) length = fold (\n _ -> n + 1) 0 id-{-#INLINE length #-}+{-# INLINE length #-} -- --------------- -- map -- ---------------@@ -1284,7 +1317,7 @@ -}  map :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r-map f =  maps (\(x :> rest) -> f x :> rest)+map f = maps (\(x :> rest) -> f x :> rest) -- loop where  --   -- loop stream = case stream of   --   Return r -> Return r@@ -1306,12 +1339,14 @@ 400 500 600++See also 'chain' for a variant of this which ignores the return value of the function and just uses the side effects. -} mapM :: Monad m => (a -> m b) -> Stream (Of a) m r -> Stream (Of b) m r mapM f = loop where   loop str = case str of     Return r       -> Return r-    Effect m        -> Effect (fmap loop m)+    Effect m       -> Effect (fmap loop m)     Step (a :> as) -> Effect $ do       a' <- f a       return (Step (a' :> loop as) )@@ -1335,7 +1370,7 @@ 49 :> ()  -}-mapM_ :: Monad m => (a -> m b) -> Stream (Of a) m r -> m r+mapM_ :: Monad m => (a -> m x) -> Stream (Of a) m r -> m r mapM_ f = loop where   loop str = case str of     Return r -> return r@@ -1350,8 +1385,7 @@  > let noteBeginning text x = putStrLn text >> return text -     this puts the-     is completely functor-general+     this is completely functor-general       @maps@ and @mapped@ obey these rules: @@ -1372,7 +1406,7 @@  mapped :: (Monad m, Functor f) => (forall x . f x -> m (g x)) -> Stream f m r -> Stream g m r mapped = mapsM-{-#INLINE mapped #-}+{-# INLINE mapped #-}  {-| A version of 'mapped' that imposes a 'Functor' constraint on the target functor rather     than the source functor. This version should be preferred if 'fmap' on the target@@ -1402,7 +1436,7 @@  {-| Fold streamed items into their monoidal sum ->>> S.mconcat $ S.take 2 $ S.map (Data.Monoid.Last . Just) (S.stdinLn)+>>> S.mconcat $ S.take 2 $ S.map (Data.Monoid.Last . Just) S.stdinLn first<Enter> last<Enter> Last {getLast = Just "last"} :> ()@@ -1426,19 +1460,19 @@ minimum_ = fold_ (\m a -> case m of Nothing_ -> Just_ a ; Just_ a' -> Just_ (min a a'))                  Nothing_                  (\m -> case m of Nothing_ -> Nothing; Just_ r -> Just r)-{-#INLINE minimum_ #-}+{-# INLINE minimum_ #-}  maximum :: (Monad m, Ord a) => Stream (Of a) m r -> m (Of (Maybe a) r) maximum = fold (\m a -> case m of Nothing_ -> Just_ a ; Just_ a' -> Just_ (max a a'))                Nothing_                (\m -> case m of Nothing_ -> Nothing; Just_ r -> Just r)-{-#INLINE maximum #-}+{-# INLINE maximum #-}  maximum_ :: (Monad m, Ord a) => Stream (Of a) m r -> m (Maybe a) maximum_ = fold_ (\m a -> case m of Nothing_ -> Just_ a ; Just_ a' -> Just_ (max a a'))                  Nothing_                  (\m -> case m of Nothing_ -> Nothing; Just_ r -> Just r)-{-#INLINE maximum_ #-}+{-# INLINE maximum_ #-}  {-| The standard way of inspecting the first item in a stream of elements, if the      stream is still \'running\'. The @Right@ case contains a@@ -1446,7 +1480,7 @@      There is no reason to prefer @inspect@ since, if the @Right@ case is exposed,      the first element in the pair will have been evaluated to whnf. -> next :: Monad m => Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))+> next    :: Monad m => Stream (Of a) m r -> m (Either r    (a, Stream (Of a) m r)) > inspect :: Monad m => Stream (Of a) m r -> m (Either r (Of a (Stream (Of a) m r)))       Interoperate with @pipes@ producers thus:@@ -1457,7 +1491,7 @@      Similarly:  > IOStreams.unfoldM (fmap (either (const Nothing) Just) . next) :: Stream (Of a) IO b -> IO (InputStream a)-> Conduit.unfoldM (fmap (either (const Nothing) Just) . next)   :: Stream (Of a) m r -> Source a m r+> Conduit.unfoldM   (fmap (either (const Nothing) Just) . next) :: Stream (Of a) m r -> Source a m r       But see 'uncons', which is better fitted to these @unfoldM@s -}@@ -1484,7 +1518,7 @@       if a == a'         then fmap (False :>) (effects rest)         else loop True rest-{-#INLINABLE notElem #-}+{-# INLINABLE notElem #-}  notElem_ :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m Bool notElem_ a' = loop True where@@ -1496,13 +1530,13 @@       if a == a'         then return False         else loop True rest-{-#INLINABLE notElem_ #-}+{-# INLINABLE notElem_ #-}   {-| Remove repeated elements from a Stream. 'nubOrd' of course accumulates a 'Data.Set.Set' of     elements that have already been seen and should thus be used with care. ->>> S.toList_ $ S.nubOrd $ S.take 5 S.readLn :: IO ([Int])+>>> S.toList_ $ S.nubOrd $ S.take 5 S.readLn :: IO [Int] 1<Enter> 2<Enter> 3<Enter>@@ -1598,7 +1632,7 @@  {-| Fold a 'Stream' of numbers into their product with the return value ->  maps' product' :: Stream (Stream (Of Int)) m r -> Stream (Of Int) m r+>  mapped product :: Stream (Stream (Of Int)) m r -> Stream (Of Int) m r -} product :: (Monad m, Num a) => Stream (Of a) m r -> m (Of a r) product = fold (*) 1 id@@ -1643,7 +1677,7 @@  {-| Repeat a monadic action /ad inf./, streaming its results. ->>>  S.toList $ S.take 2 $ repeatM getLine+>>> S.toList $ S.take 2 $ repeatM getLine one<Enter> two<Enter> ["one","two"]@@ -1701,7 +1735,7 @@       Just a  -> return (Step (a :> loop)) {-# INLINABLE reread #-} -{-| Strict left scan, streaming, e.g. successive partial results. The seed +{-| Strict left scan, streaming, e.g. successive partial results. The seed     is yielded first, before any action of finding the next element is performed.  @@ -1723,34 +1757,34 @@ -} scan :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> Stream (Of b) m r scan step begin done str = Step (done begin :> loop begin str)-  where                   -  loop !acc stream = do+  where+  loop !acc stream =     case stream of       Return r -> Return r       Effect m -> Effect (fmap (loop acc) m)-      Step (a :> rest) -> -        let !acc' = step acc a +      Step (a :> rest) ->+        let !acc' = step acc a         in Step (done acc' :> loop acc' rest)-{-#INLINABLE scan #-}+{-# INLINABLE scan #-}  {-| Strict left scan, accepting a monadic function. It can be used with     'FoldM's from @Control.Foldl@ using 'impurely'. Here we yield     a succession of vectors each recording ->>> let v =  L.impurely scanM L.vector $ each [1..4::Int] :: Stream (Of (U.Vector Int)) IO ()+>>> let v = L.impurely scanM L.vectorM $ each [1..4::Int] :: Stream (Of (Vector Int)) IO () >>> S.print v-fromList []-fromList [1]-fromList [1,2]-fromList [1,2,3]-fromList [1,2,3,4]+[]+[1]+[1,2]+[1,2,3]+[1,2,3,4]  -} scanM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream (Of a) m r -> Stream (Of b) m r scanM step begin done str = Effect $ do     x <- begin     b <- done x-    return (Step (b :> loop x str))  +    return (Step (b :> loop x str))   where     loop !x stream = case stream of -- note we have already yielded from x       Return r -> Return r@@ -1765,8 +1799,7 @@         ) {-# INLINABLE scanM #-} -{- Label each element in a stream with a value accumulated according to a fold.-+{-| Label each element in a stream with a value accumulated according to a fold.  >>> S.print $ S.scanned (*) 1 id $ S.each [100,200,300] (100,100)@@ -1780,16 +1813,14 @@  -} -data Maybe' a = Just' a | Nothing'- scanned :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> Stream (Of (a,b)) m r scanned step begin done = loop Nothing' begin   where-    loop !m !x stream = do+    loop !m !x stream =       case stream of         Return r -> return r         Effect mn  -> Effect $ fmap (loop m x) mn-        Step (a :> rest) -> do+        Step (a :> rest) ->           case m of             Nothing' -> do               let !acc = step x a@@ -1801,30 +1832,7 @@               loop (Just' a) (step x a) rest {-# INLINABLE scanned #-} --{-| Streams the number of seconds from the beginning of action--    Thus, to mark times of user input we might write something like:-->>> S.toList $ S.take 3 $ S.zip S.seconds S.stdinLn-a<Enter>-b<Enter>-c<Enter>-[(0.0,"a"),(1.088711,"b"),(3.7289649999999996,"c")] :> ()--   To restrict user input to some number of seconds, we might write:-->>> S.toList $ S.map fst $ S.zip S.stdinLn $ S.takeWhile (< 3) S.seconds-one<Enter>-two<Enter>-three<Enter>-four<Enter>-five<Enter>-["one","two","three","four","five"] :> ()--   This of course does not interrupt an action that has already begun.--  -}+data Maybe' a = Just' a | Nothing'  -- --------------- -- sequence@@ -1875,15 +1883,16 @@ 55 :> ()  >>> (n :> rest)  <- S.sum $ S.splitAt 3 $ each [1..10]->>> print n+>>> System.IO.print n 6 >>> (m :> rest') <- S.sum $ S.splitAt 3 rest->>> print m+>>> System.IO.print m 15 >>> S.print rest' 7 8 9+10  -} sum :: (Monad m, Num a) => Stream (Of a) m r -> m (Of a r)@@ -1926,7 +1935,7 @@          if a /= t             then Step (fmap loop (yield a >> break (== t) rest))             else loop rest-{-#INLINABLE split #-}+{-# INLINABLE split #-}  {-| Split a succession of layers after some number, returning a streaming or     effectful pair. This function is the same as the 'splitsAt' exported by the@@ -1958,7 +1967,7 @@     Return r         -> Return r     Effect m         -> Effect (fmap loop m)     Step (a :> rest) -> Step (loop rest <$ f a)-{-#INLINABLE subst #-}+{-# INLINABLE subst #-} -- --------------- -- take -- ---------------@@ -1972,7 +1981,7 @@ >>> S.toList $ S.take 3 $ each "with" "wit" :> () ->>> runResourceT $ S.stdoutLn $ S.take 3 $ S.readFile "stream.hs"+>>> S.readFile "stream.hs" (S.stdoutLn . S.take 3) import Streaming import qualified Streaming.Prelude as S import Streaming.Prelude (each, next, yield)@@ -2030,7 +2039,7 @@ {-# INLINE takeWhileM #-}  -{-| Convert an effectful 'Stream (Of a)' into a list of @as@+{-| Convert an effectful @Stream (Of a)@ into a list of @as@      Note: Needless to say, this function does not stream properly.     It is basically the same as Prelude 'mapM' which, like 'replicateM',@@ -2045,22 +2054,23 @@  {-| Convert an effectful 'Stream' into a list alongside the return value ->  mapped toList :: Stream (Stream (Of a)) m r -> Stream (Of [a]) m+>  mapped toList :: Stream (Stream (Of a) m) m r -> Stream (Of [a]) m r -    Like 'toList_', 'toList' breaks streaming; unlike 'toList_' it /preserves the return value/ +    Like 'toList_', 'toList' breaks streaming; unlike 'toList_' it /preserves the return value/     and thus is frequently useful with e.g. 'mapped'  >>> S.print $ mapped S.toList $ chunksOf 3 $ each [1..9] [1,2,3] [4,5,6] [7,8,9]+ >>> S.print $ mapped S.toList $ chunksOf 2 $ S.replicateM 4 getLine s<Enter> t<Enter> ["s","t"] u<Enter> v<Enter>-["u","v"] +["u","v"] -} toList :: Monad m => Stream (Of a) m r -> m (Of [a] r) toList = fold (\diff a ls -> diff (a: ls)) id (\diff -> diff [])@@ -2121,6 +2131,18 @@ {-# INLINABLE unfoldr #-}  -- ---------------------------------------+-- untilLeft+-- ---------------------------------------+untilLeft :: Monad m => m (Either r a) -> Stream (Of a) m r+untilLeft act = Effect loop where+  loop = do+    e <- act+    case e of+      Right a -> return (Step (a :> Effect loop))+      Left r -> return (Return r)+{-# INLINABLE untilLeft #-}++-- --------------------------------------- -- untilRight -- --------------------------------------- untilRight :: Monad m => m (Either a r) -> Stream (Of a) m r@@ -2130,7 +2152,7 @@     case e of       Right r -> return (Return r)       Left a -> return (Step (a :> Effect loop))-{-#INLINABLE untilRight #-}+{-# INLINABLE untilRight #-}  -- --------------------------------------- -- with@@ -2144,7 +2166,7 @@ > with = flip subst > subst = flip with ->>> with (each [1..3]) (yield . show) & intercalates (yield "--") & S.stdoutLn+>>> with (each [1..3]) (yield . Prelude.show) & intercalates (yield "--") & S.stdoutLn 1 -- 2@@ -2157,7 +2179,7 @@     Return r         -> Return r     Effect m         -> Effect (fmap loop m)     Step (a :> rest) -> Step (loop rest <$ f a)-{-#INLINABLE with #-}+{-# INLINABLE with #-}  -- --------------------------------------- -- yield@@ -2169,7 +2191,7 @@ hello  >>> S.sum $ do {yield 1; yield 2; yield 3}-6+6 :> ()  >>> let number = lift (putStrLn "Enter a number:") >> lift readLn >>= yield :: Stream (Of Int) IO () >>> S.toList $ do {number; number; number}@@ -2189,18 +2211,18 @@  -- | Zip two 'Stream's zip :: Monad m-    => (Stream (Of a) m r)-    -> (Stream (Of b) m r)-    -> (Stream (Of (a,b)) m r)+    => Stream (Of a) m r+    -> Stream (Of b) m r+    -> Stream (Of (a,b)) m r zip = zipWith (,) {-# INLINE zip #-}  -- | Zip two 'Stream's using the provided combining function zipWith :: Monad m     => (a -> b -> c)-    -> (Stream (Of a) m r)-    -> (Stream (Of b) m r)-    -> (Stream (Of c) m r)+    -> Stream (Of a) m r+    -> Stream (Of b) m r+    -> Stream (Of c) m r zipWith f = loop   where     loop str0 str1 = case str0 of@@ -2241,10 +2263,10 @@  -- | Zip three 'Stream's together zip3 :: Monad m-    => (Stream (Of a) m r)-    -> (Stream (Of b) m r)-    -> (Stream (Of c) m r)-    -> (Stream (Of (a,b,c)) m r)+     => Stream (Of a) m r+     -> Stream (Of b) m r+     -> Stream (Of c) m r+     -> Stream (Of (a,b,c)) m r zip3 = zipWith3 (,,) {-# INLINABLE zip3 #-} @@ -2292,7 +2314,7 @@ -}  readLn :: (MonadIO m, Read a) => Stream (Of a) m ()-readLn = loop where +readLn = loop where   loop = do     eof <- liftIO IO.isEOF     unless eof $ do@@ -2307,7 +2329,7 @@      Terminates on end of input ->>> IO.withFile "/usr/share/dict/words" IO.ReadMode $ S.stdoutLn . S.take 3 . S.drop 50000 .  S.fromHandle+>>> IO.withFile "/usr/share/dict/words" IO.ReadMode $ S.stdoutLn . S.take 3 . S.drop 50000 . S.fromHandle deflagrator deflate deflation@@ -2348,7 +2370,6 @@ "hello" world<Enter> "world"->>>  -} print :: (MonadIO m, Show a) => Stream (Of a) m r -> m r@@ -2406,7 +2427,7 @@ hello<Enter> world<Enter> ->>> S.stdoutLn $ S.readFile "lines.txt"+>>> S.readFile "lines.txt" S.stdoutLn hello world @@ -2431,106 +2452,33 @@ stdoutLn' :: MonadIO m => Stream (Of String) m r -> m r stdoutLn' = toHandle IO.stdout ---- -- * Producers--- -- $producers---   stdinLn  ----- , readLn ----- , fromHandle ----- , repeatM ----- , replicateM -------- -- * Consumers--- -- $consumers--- , stdoutLn ----- , stdoutLn' ----- , mapM_ ----- , print ----- , toHandle ----- , effects -------- -- * Pipes--- -- $pipes--- , map ----- , mapM ----- , sequence ----- , mapFoldable ----- , filter ----- , filterM ----- , take ----- , takeWhile ----- , takeWhile' ----- , drop ----- , dropWhile ----- , concat ----- , elemIndices--- , findIndices--- , scan ----- , scanM ----- , chain ----- , read ----- , show ----- , seq -------- -- * Folds--- -- $folds--- , fold ----- , fold' ----- , foldM ----- , foldM' ----- , all--- , any--- , and--- , or--- , elem--- , notElem--- , find--- , findIndex--- , head--- , index--- , last--- , length--- , maximum--- , minimum--- , null--- , sum ----- , product ----- , toList ----- , toListM ----- , toListM' -------- -- * Zips--- , zip ----- , zipWith ------ distinguish :: (a -> Bool) -> Of a r -> Sum (Of a) (Of a) r distinguish predicate (a :> b) = if predicate a then InR (a :> b) else InL (a :> b)-{-#INLINE distinguish #-}+{-# INLINE distinguish #-}  sumToEither ::Sum (Of a) (Of b) r ->  Of (Either a b) r sumToEither s = case s of   InL (a :> r) -> Left a :> r   InR (b :> r) -> Right b :> r-{-#INLINE sumToEither #-}+{-# INLINE sumToEither #-}  eitherToSum :: Of (Either a b) r -> Sum (Of a) (Of b) r eitherToSum s = case s of   Left a :> r  -> InL (a :> r)   Right b :> r -> InR (b :> r)-{-#INLINE eitherToSum #-}+{-# INLINE eitherToSum #-}  composeToSum ::  Compose (Of Bool) f r -> Sum f f r composeToSum x = case x of   Compose (True :> f) -> InR f   Compose (False :> f) -> InL f-{-#INLINE composeToSum #-}+{-# INLINE composeToSum #-}  sumToCompose :: Sum f f r -> Compose (Of Bool) f r sumToCompose x = case x of   InR f -> Compose (True :> f)   InL f -> Compose (False :> f)-{-#INLINE sumToCompose #-}+{-# INLINE sumToCompose #-}  {-| Store the result of any suitable fold over a stream, keeping the stream for     further manipulation. @store f = f . copy@ :@@ -2556,7 +2504,7 @@    simultaneously, and in constant memory -- as they would be if,    say, you linked them together with @Control.Fold@: ->>> L.impurely S.foldM (liftA3 (\a b c -> (b,c)) (L.sink print) (L.generalize L.sum) (L.generalize L.product)) $ each [1..4]+>>> L.impurely S.foldM (liftA3 (\a b c -> (b, c)) (L.sink Prelude.print) (L.generalize L.sum) (L.generalize L.product)) $ each [1..4] 1 2 3@@ -2567,16 +2515,16 @@    than the corresponding succession of uses of 'store', but by    constant factor that will be completely dwarfed when any IO is at issue. -   But 'store' / 'copy' is /much/ more powerful, as you can see by reflecting on+   But 'store' \/ 'copy' is /much/ more powerful, as you can see by reflecting on    uses like this: ->>> S.sum $ S.store (S.sum . mapped S.product . chunksOf 2) $ S.store (S.product . mapped S.sum . chunksOf 2 )$ each [1..6]+>>> S.sum $ S.store (S.sum . mapped S.product . chunksOf 2) $ S.store (S.product . mapped S.sum . chunksOf 2) $ each [1..6] 21 :> (44 :> (231 :> ()))     It will be clear that this cannot be reproduced with any combination of lenses,    @Control.Fold@ folds, or the like.  (See also the discussion of 'copy'.) -   It would conceivable be clearer to import a series of specializations of 'store'.+   It would conceivably be clearer to import a series of specializations of 'store'.    It is intended to be used at types like these:  > storeM ::  (forall s m . Monad m => Stream (Of a) m s -> m (Of b s))@@ -2584,12 +2532,12 @@ > storeM = store > > storeMIO :: (forall s m . MonadIO m => Stream (Of a) m s -> m (Of b s))->          -> ( MonadIO n => Stream (Of a) n r -> Stream (Of a) n (Of b r)+>          -> (MonadIO n => Stream (Of a) n r -> Stream (Of a) n (Of b r) > storeMIO = store      It is clear from these types that we are just using the general instances: -> instance (Functor f, Monad m )  => Monad (Stream f m)+> instance (Functor f, Monad m)   => Monad (Stream f m) > instance (Functor f, MonadIO m) => MonadIO (Stream f m)      We thus can't be touching the elements of the stream, or the final return value.@@ -2597,7 +2545,7 @@     like 'MonadResource'.  Thus I can independently filter and write to one file, but     nub and write to another, or interact with a database and a logfile and the like: ->>> runResourceT $ (S.writeFile "hello2.txt" . S.nubOrd) $ store (S.writeFile "hello.txt" . S.filter (/= "world")) $ each ["hello", "world", "goodbye", "world"]+>>> (S.writeFile "hello2.txt" . S.nubOrd) $ store (S.writeFile "hello.txt" . S.filter (/= "world")) $ each ["hello", "world", "goodbye", "world"] >>> :! cat hello.txt hello goodbye@@ -2612,7 +2560,7 @@   :: Monad m =>      (Stream (Of a) (Stream (Of a) m) r -> t) -> Stream (Of a) m r -> t store f x = f (copy x)-{-#INLINE store #-}+{-# INLINE store #-}  {-| Duplicate the content of stream, so that it can be acted on twice in different ways,     but without breaking streaming. Thus, with @each [1,2]@ I might do:@@ -2627,10 +2575,10 @@     With copy, I can do these simultaneously:  >>> S.print $ S.stdoutLn $ S.copy $ each ["one","two"]-one "one"-two+one "two"+two      'copy' should be understood together with 'effects' and is subject to the rules @@ -2656,7 +2604,7 @@     using 'Control.Foldl.handles' on an appropriate lens. Some such     manipulations are simpler and more 'Data.List'-like, using 'copy': ->>> L.purely S.fold (liftA2 (,) (L.handles (filtered odd) L.sum) (L.handles (filtered even) L.product)) $ each [1..10]+>>> L.purely S.fold (liftA2 (,) (L.handles (L.filtered odd) L.sum) (L.handles (L.filtered even) L.product)) $ each [1..10] (25,3840) :> ()       becomes@@ -2703,13 +2651,15 @@     Return r         -> Return r     Effect m         -> Effect (fmap loop (lift m))     Step (a :> rest) -> Effect (Step (a :> Return (Step (a :> loop rest))))-{-#INLINABLE copy#-}+{-# INLINABLE copy#-} +{-| An alias for @copy@.+-} duplicate   :: Monad m =>      Stream (Of a) m r -> Stream (Of a) (Stream (Of a) m) r duplicate = copy-{-#INLINE duplicate #-}+{-# INLINE duplicate #-}  {-| The type @@ -2725,7 +2675,7 @@    This @unzip@ does    stream, though of course you can spoil this by using e.g. 'toList': ->>> let xs =  map (\x-> (x,show x)) [1..5::Int]+>>> let xs = Prelude.map (\x -> (x, Prelude.show x)) [1..5 :: Int]  >>> S.toList $ S.toList $ S.unzip (S.each xs) ["1","2","3","4","5"] :> ([1,2,3,4,5] :> ())@@ -2770,7 +2720,7 @@    Return r -> Return r    Effect m -> Effect (fmap loop (lift m))    Step ((a,b):> rest) -> Step (a :> Effect (Step (b :> Return (loop rest))))-{-#INLINABLE unzip #-}+{-# INLINABLE unzip #-}   @@ -2838,7 +2788,7 @@           LT -> Step (a :> loop rest0 str1)           EQ -> Step (a :> loop rest0 str1) -- left-biased           GT -> Step (b :> loop str0 rest1)-{-# INLINABLE mergeBy #-}        +{-# INLINABLE mergeBy #-}  {- $maybes     These functions discard the 'Nothing's that they encounter. They are analogous@@ -2847,7 +2797,7 @@  {-| The 'catMaybes' function takes a 'Stream' of 'Maybe's and returns     a 'Stream' of all of the 'Just' values. 'concat' has the same behavior,-    but is more general; it works for any foldable container type. +    but is more general; it works for any foldable container type. -} catMaybes :: Monad m => Stream (Of (Maybe a)) m r -> Stream (Of a) m r catMaybes = loop where@@ -2857,12 +2807,12 @@     Step (ma :> snext) -> case ma of       Nothing -> loop snext       Just a -> Step (a :> loop snext)-{-#INLINABLE catMaybes #-}+{-# INLINABLE catMaybes #-}  {-| The 'mapMaybe' function is a version of 'map' which can throw out elements. In particular,     the functional argument returns something of type @'Maybe' b@. If this is 'Nothing', no element     is added on to the result 'Stream'. If it is @'Just' b@, then @b@ is included in the result 'Stream'.-    + -} mapMaybe :: Monad m => (a -> Maybe b) -> Stream (Of a) m r -> Stream (Of b) m r mapMaybe phi = loop where@@ -2872,42 +2822,42 @@     Step (a :> snext) -> case phi a of       Nothing -> loop snext       Just b -> Step (b :> loop snext)-{-#INLINABLE mapMaybe #-}+{-# INLINABLE mapMaybe #-} -{-| 'slidingWindow' accumulates the first @n@ elements of a stream, +{-| 'slidingWindow' accumulates the first @n@ elements of a stream,      update thereafter to form a sliding window of length @n@.-     It follows the behavior of the slidingWindow function in +     It follows the behavior of the slidingWindow function in      <https://hackage.haskell.org/package/conduit-combinators-1.0.4/docs/Data-Conduit-Combinators.html#v:slidingWindow conduit-combinators>. ->>> S.print $ slidingWindow 4 $ S.each "123456"+>>> S.print $ S.slidingWindow 4 $ S.each "123456" fromList "1234" fromList "2345" fromList "3456"  -} -slidingWindow :: Monad m -  => Int -  -> Stream (Of a) m b +slidingWindow :: Monad m+  => Int+  -> Stream (Of a) m b   -> Stream (Of (Seq.Seq a)) m b-slidingWindow n = setup (max 1 n :: Int) mempty -  where -    window !sequ str = do -      e <- lift (next str) -      case e of +slidingWindow n = setup (max 1 n :: Int) mempty+  where+    window !sequ str = do+      e <- lift (next str)+      case e of         Left r -> return r-        Right (a,rest) -> do +        Right (a,rest) -> do           yield (sequ Seq.|> a)           window (Seq.drop 1 $ sequ Seq.|> a) rest     setup 0 !sequ str = do-       yield sequ -       window (Seq.drop 1 sequ) str -    setup m sequ str = do -      e <- lift $ next str -      case e of +       yield sequ+       window (Seq.drop 1 sequ) str+    setup m sequ str = do+      e <- lift $ next str+      case e of         Left r ->  yield sequ >> return r         Right (x,rest) -> setup (m-1) (sequ Seq.|> x) rest-{-#INLINABLE slidingWindow #-}+{-# INLINABLE slidingWindow #-}  -- | Map monadically over a stream, producing a new stream --   only containing the 'Just' values.@@ -2916,8 +2866,8 @@   loop stream = case stream of     Return r -> Return r     Effect m -> Effect (fmap loop m)-    Step (a :> snext) -> Effect $ do+    Step (a :> snext) -> Effect $       flip fmap (phi a) $ \x -> case x of         Nothing -> loop snext         Just b -> Step (b :> loop snext)-{-#INLINABLE mapMaybeM #-}+{-# INLINABLE mapMaybeM #-}
streaming.cabal view
@@ -1,16 +1,16 @@ name:                streaming-version:             0.2.2.0+version:             0.2.3.0 cabal-version:       >=1.10 build-type:          Simple synopsis:            an elementary streaming prelude and general stream type. -description:         This package contains two modules, <http://hackage.haskell.org/package/streaming/docs/Streaming.html Streaming> +description:         This package contains two modules, <http://hackage.haskell.org/package/streaming/docs/Streaming.html Streaming>                      and <http://hackage.haskell.org/package/streaming/docs/Streaming-Prelude.html Streaming.Prelude>.                      The principal module, <http://hackage.haskell.org/package/streaming-0.1.4.3/docs/Streaming-Prelude.html Streaming.Prelude>, exports an elementary streaming prelude focused on                      a simple \"source\" or \"producer\" type, namely @Stream (Of a) m r@.                      This is a sort of effectful version of                      @([a],r)@ in which successive elements of type @a@ arise from some sort of monadic-                     action before the succession ends with a value of type @r@. +                     action before the succession ends with a value of type @r@.                      Everything in the library is organized to make                      programming with this type as simple as possible,                      by the simple expedient of making it as close to @Prelude@@@ -21,11 +21,11 @@                      > 1<Enter>                      > 2<Enter>                      > 3<Enter>-                     > 6 :> () +                     > 6 :> ()                      .                      sums the first three valid integers from user input. Similarly,                      .-                     > >>> S.stdoutLn $ S.map (map toUpper) $ S.take 2 S.stdinLn +                     > >>> S.stdoutLn $ S.map (map toUpper) $ S.take 2 S.stdinLn                      > hello<Enter>                      > HELLO                      > world!<Enter>@@ -33,13 +33,13 @@                      .                      upper-cases the first two lines from stdin as they arise,                      and sends them to stdout. And so on,-                     with filtering, mapping, breaking, chunking, zipping, unzipping, replicating -                     and so forth: +                     with filtering, mapping, breaking, chunking, zipping, unzipping, replicating+                     and so forth:                      we program with streams of @Int@s or @String@s directly as                      if they constituted something like a list. That's because streams really do constitute something-                     like a list, and the associated operations can mostly have the same names. -                     (A few, like @reverse@, don't stream and thus disappear; -                     others like @unzip@ are here given properly streaming formulation for the first time.) +                     like a list, and the associated operations can mostly have the same names.+                     (A few, like @reverse@, don't stream and thus disappear;+                     others like @unzip@ are here given properly streaming formulation for the first time.)                      And we everywhere                      oppose \"extracting a pure list from IO\",                      which is the origin of typical Haskell memory catastrophes.@@ -53,7 +53,7 @@                      .                      > main = mapM newIORef [1..10^8::Int] >>= mapM readIORef >>= mapM_ print                      .-                     The new user notices that this exhausts memory, and worries about the efficiency of Haskell @IORefs@. +                     The new user notices that this exhausts memory, and worries about the efficiency of Haskell @IORefs@.                      But of course it exhausts memory! Look what it says!                      The problem is immediately cured by writing                      .@@ -100,7 +100,7 @@                      elementary streaming library - since one possesses @Stream ((,) a) m r@                      or equivalently @Stream (Of a) m r@. This                      is the type of a \'generator\' or \'producer\' or \'source\' or whatever-                     you call an effectful stream of items. +                     you call an effectful stream of items.                      /The present Streaming.Prelude is thus the simplest streaming library that can replicate anything like the API of the Prelude and Data.List/.                      .                      The emphasis of the library is on interoperation; for@@ -117,7 +117,7 @@                      a complex framework, but in a way that integrates transparently with                      the rest of Haskell, using ideas - e.g. rank 2 types, which are here                      implicit or explicit in most mapping - that the user can carry elsewhere,-                     rather than chaining her understanding to the curiosities of +                     rather than chaining her understanding to the curiosities of                      a so-called streaming IO framework (as necessary as that is for certain purposes.)                      .                      See the@@ -186,12 +186,13 @@ license:             BSD3 license-file:        LICENSE author:              michaelt-maintainer:          andrew.thaddeus@gmail.com, what_is_it_to_do_anything@yahoo.com+maintainer:          andrew.thaddeus@gmail.com, chessai1996@gmail.com stability:           Experimental homepage:            https://github.com/haskell-streaming/streaming bug-reports:         https://github.com/haskell-streaming/streaming/issues category:            Data, Pipes, Streaming extra-source-files:  README.md, changelog.md+tested-with:         GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.2  source-repository head     type: git@@ -203,24 +204,21 @@     , Streaming.Prelude     , Streaming.Internal     , Data.Functor.Of-  other-extensions:-      RankNTypes-    , CPP-    , StandaloneDeriving-    , FlexibleContexts-    , DeriveDataTypeable-    , DeriveFoldable-    , DeriveFunctor-    , DeriveTraversable-    , UndecidableInstances   build-depends:       base >=4.8 && <5     , mtl >=2.1 && <2.3     , mmorph >=1.0 && <1.2-    , semigroups >= 0.18 && <0.19-    , transformers >=0.5 && <0.6+    , transformers >=0.4 && <0.6     , transformers-base < 0.5     , ghc-prim     , containers-  hs-source-dirs:    src-  default-language:  Haskell2010++  if !impl(ghc >= 8.0)+    build-depends:+        fail == 4.9.*+      , semigroups >= 0.18 && <0.20++  hs-source-dirs:+    src+  default-language:+    Haskell2010