@@ -599,55 +599,42 @@ module Streamly.Internal.Data.Stream.IsStream
601import Control.Concurrent (threadDelay)
601import Control.Concurrent (threadDelay)
602−import Control.Exception (Exception, assert)
602+import Control.Exception (assert)
603−import Control.Monad (void)
604−import Control.Monad.Catch (MonadCatch, MonadThrow)
605import Control.Monad.IO.Class (MonadIO(..))
603import Control.Monad.IO.Class (MonadIO(..))
606−import Control.Monad.Trans.Reader (ReaderT)
607−import Control.Monad.Trans.State.Strict (StateT)
608−import Control.Monad.Trans.Class (MonadTrans(..))
609−import Control.Monad.Trans.Control (MonadBaseControl)
610−import Data.Either (isLeft, isRight)
611−import Data.Functor.Identity (Identity (..))
612import Data.Kind (Type)
604import Data.Kind (Type)
613import Data.Heap (Entry(..))
605import Data.Heap (Entry(..))
614−import Data.Maybe (isJust, fromJust, isNothing)
606+import Data.Maybe (isNothing)
615−import Data.Void (Void)
616import Foreign.Storable (Storable)
607import Foreign.Storable (Storable)
617−import Streamly.Internal.BaseCompat (fromLeft, fromRight)
618import Streamly.Internal.Data.Stream.Enumeration
608import Streamly.Internal.Data.Stream.Enumeration
619 (Enumerable(..), enumerate, enumerateTo)
609 (Enumerable(..), enumerate, enumerateTo)
620−import Streamly.Internal.Data.Fold.Types (Fold (..), Fold2 (..))
610+import Streamly.Internal.Data.Fold.Types (Fold (..))
621−import Streamly.Internal.Data.Parser (Parser (..))
622−import Streamly.Internal.Data.Unfold.Types (Unfold)
623−import Streamly.Internal.Data.Array.Storable.Foreign.Types (Array, writeNUnsafe)
611+import Streamly.Internal.Data.Array.Storable.Foreign.Types (Array)
624−import Streamly.Internal.Data.SVar (MonadAsync, defState, Rate (..))
612+import Streamly.Internal.Data.SVar (MonadAsync, Rate (..))
625−import Streamly.Internal.Data.Stream.Ahead (AheadT, Ahead, ahead, aheadly)
613+import Streamly.Internal.Data.Stream.Ahead (AheadT, Ahead, aheadly)
626import Streamly.Internal.Data.Stream.Async
614import Streamly.Internal.Data.Stream.Async
627− ( AsyncT, Async, WAsyncT, WAsync, mkAsync, async, asyncly, wAsync
615+ ( AsyncT, Async, WAsyncT, WAsync, mkAsync, asyncly
628 , wAsyncly)
616 , wAsyncly)
629import Streamly.Internal.Data.Stream.Combinators
617import Streamly.Internal.Data.Stream.Combinators
630− ( inspectMode, maxBuffer, maxThreads, maxYields, rate, avgRate, minRate
618+ ( inspectMode, maxBuffer, maxThreads, rate, avgRate, minRate
631 , maxRate, constRate)
619 , maxRate, constRate)
632import Streamly.Internal.Data.Stream.Parallel
620import Streamly.Internal.Data.Stream.Parallel
633− ( ParallelT, Parallel, parallel, parallely)
621+ ( ParallelT, Parallel, parallely)
634−import Streamly.Internal.Data.Stream.Prelude
635− (fromStreamS, toStreamS, concatFoldableWith, concatMapFoldableWith
636− , concatForFoldableWith)
637−import Streamly.Internal.Data.Stream.StreamD (fromStreamD, toStreamD)
638import Streamly.Internal.Data.Stream.StreamK (IsStream((|:), consM), adapt)
622import Streamly.Internal.Data.Stream.StreamK (IsStream((|:), consM), adapt)
639import Streamly.Internal.Data.Stream.Serial
623import Streamly.Internal.Data.Stream.Serial
640− ( SerialT, WSerialT, Serial, WSerial, serial, wSerial, serially
624+ ( SerialT, WSerialT, Serial, WSerial, serially
641 , wSerially)
625 , wSerially)
642import Streamly.Internal.Data.Stream.Zip
626import Streamly.Internal.Data.Stream.Zip
643 ( ZipSerialM, ZipSerial, ZipAsyncM, ZipAsync, zipSerially, zipAsyncly)
627 ( ZipSerialM, ZipSerial, ZipAsyncM, ZipAsync, zipSerially, zipAsyncly)
644−import Streamly.Internal.Data.Pipe.Types (Pipe (..))
645import Streamly.Internal.Data.Time.Units
628import Streamly.Internal.Data.Time.Units
646 ( AbsTime, MilliSecond64(..), addToAbsTime, toRelTime
629 ( AbsTime, MilliSecond64(..), addToAbsTime, toRelTime
647− , toAbsTime, TimeUnit64, RelTime64, addToAbsTime64)
630+ , toAbsTime, RelTime64)
648−import Streamly.Internal.Data.IORef.Prim (Prim, IORef)
649import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
631import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
633+import Streamly.Internal.Data.Stream.IsStream.Generate
634+import Streamly.Internal.Data.Stream.IsStream.Eliminate
635+import Streamly.Internal.Data.Stream.IsStream.Transform
636+import Streamly.Internal.Data.Stream.IsStream.Exceptions
651import qualified Streamly.Internal.Data.Array.Storable.Foreign as A
638import qualified Streamly.Internal.Data.Array.Storable.Foreign as A
652import qualified Streamly.Internal.Data.Fold as FL
639import qualified Streamly.Internal.Data.Fold as FL
653import qualified Streamly.Internal.Data.Stream.Prelude as P
640import qualified Streamly.Internal.Data.Stream.Prelude as P
@@ -656,17 +643,8 @@ import qualified Streamly.Internal.Data.Stream.StreamD as D
656import qualified Streamly.Internal.Data.Stream.Serial as Serial
643import qualified Streamly.Internal.Data.Stream.Serial as Serial
657import qualified Streamly.Internal.Data.Stream.Parallel as Par
644import qualified Streamly.Internal.Data.Stream.Parallel as Par
658import qualified Streamly.Internal.Data.Stream.Zip as Z
645import qualified Streamly.Internal.Data.Stream.Zip as Z
659−import qualified Streamly.Internal.Data.Parser.ParserK.Types as PRK
660−import qualified Streamly.Internal.Data.Parser.ParserD as PRD
661import qualified Data.Heap as H
646import qualified Data.Heap as H
662import qualified Data.Map.Strict as Map
647import qualified Data.Map.Strict as Map
663−import qualified Prelude
664−import qualified System.IO as IO
665−#ifdef USE_STREAMK_ONLY
666−import qualified Streamly.Internal.Data.Stream.StreamK as S
668−import qualified Streamly.Internal.Data.Stream.StreamD as S
671import Prelude hiding
649import Prelude hiding
672 ( filter, drop, dropWhile, take, takeWhile, zipWith, foldr
650 ( filter, drop, dropWhile, take, takeWhile, zipWith, foldr
@@ -676,407 +654,10 @@ import Prelude hiding
676 , scanl, scanl1, replicate, concatMap, span, splitAt, break
654 , scanl, scanl1, replicate, concatMap, span, splitAt, break
677 , repeat, concat, mconcat)
655 , repeat, concat, mconcat)
679−------------------------------------------------------------------------------
681−------------------------------------------------------------------------------
683−-- | Decompose a stream into its head and tail. If the stream is empty, returns
684−-- 'Nothing'. If the stream is non-empty, returns @Just (a, ma)@, where @a@ is
685−-- the head of the stream and @ma@ its tail.
687−-- This is a brute force primitive. Avoid using it as long as possible, use it
688−-- when no other combinator can do the job. This can be used to do pretty much
689−-- anything in an imperative manner, as it just breaks down the stream into
690−-- individual elements and we can loop over them as we deem fit. For example,
691−-- this can be used to convert a streamly stream into other stream types.
694−{-# INLINE uncons #-}
695−uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
696−uncons m = K.uncons (K.adapt m)
698−------------------------------------------------------------------------------
699−-- Generation by Unfolding
700−------------------------------------------------------------------------------
706−-- Nothing -> 'K.nil'
707−-- Just (a, b) -> a \`cons` unfoldr step b
710−-- Build a stream by unfolding a /pure/ step function @step@ starting from a
711−-- seed @s@. The step function returns the next element in the stream and the
712−-- next seed value. When it is done it returns 'Nothing' and the stream ends.
719−-- else Just (b, b + 1)
720−-- in toList $ unfoldr f 0
727−{-# INLINE_EARLY unfoldr #-}
728−unfoldr :: (Monad m, IsStream t) => (b -> Maybe (a, b)) -> b -> t m a
729−unfoldr step seed = fromStreamS (S.unfoldr step seed)
730−{-# RULES "unfoldr fallback to StreamK" [1]
731− forall a b. S.toStreamK (S.unfoldr a b) = K.unfoldr a b #-}
733−-- | Build a stream by unfolding a /monadic/ step function starting from a
734−-- seed. The step function returns the next element in the stream and the next
735−-- seed value. When it is done it returns 'Nothing' and the stream ends. For
741−-- then return Nothing
742−-- else print b >> return (Just (b, b + 1))
743−-- in drain $ unfoldrM f 0
751−-- When run concurrently, the next unfold step can run concurrently with the
752−-- processing of the output of the previous step. Note that more than one step
753−-- cannot run concurrently as the next step depends on the output of the
757−-- (asyncly $ S.unfoldrM (\\n -> liftIO (threadDelay 1000000) >> return (Just (n, n + 1))) 0)
758−-- & S.foldlM' (\\_ a -> threadDelay 1000000 >> print a) ()
764−{-# INLINE_EARLY unfoldrM #-}
765−unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
766−unfoldrM = K.unfoldrM
768−{-# RULES "unfoldrM serial" unfoldrM = unfoldrMSerial #-}
769−{-# INLINE_EARLY unfoldrMSerial #-}
770−unfoldrMSerial :: MonadAsync m => (b -> m (Maybe (a, b))) -> b -> SerialT m a
771−unfoldrMSerial = Serial.unfoldrM
773−{-# RULES "unfoldrM wSerial" unfoldrM = unfoldrMWSerial #-}
774−{-# INLINE_EARLY unfoldrMWSerial #-}
775−unfoldrMWSerial :: MonadAsync m => (b -> m (Maybe (a, b))) -> b -> WSerialT m a
776−unfoldrMWSerial = Serial.unfoldrM
778−{-# RULES "unfoldrM zipSerial" unfoldrM = unfoldrMZipSerial #-}
779−{-# INLINE_EARLY unfoldrMZipSerial #-}
780−unfoldrMZipSerial :: MonadAsync m => (b -> m (Maybe (a, b))) -> b -> ZipSerialM m a
781−unfoldrMZipSerial = Serial.unfoldrM
783−-- | Convert an 'Unfold' into a stream by supplying it an input seed.
785−-- >>> unfold (UF.replicateM 10) (putStrLn "hello")
788−{-# INLINE unfold #-}
789−unfold :: (IsStream t, Monad m) => Unfold m a b -> a -> t m b
790−unfold unf x = fromStreamD $ D.unfold unf x
792−-- | Convert an 'Unfold' with a closed input end into a stream.
795−{-# INLINE unfold0 #-}
796−unfold0 :: (IsStream t, Monad m) => Unfold m Void b -> t m b
797−unfold0 unf = unfold unf (error "unfold0: unexpected void evaluation")
799−------------------------------------------------------------------------------
800−-- Specialized Generation
801−------------------------------------------------------------------------------
803−-- Faster than yieldM because there is no bind.
807−-- yield a = a \`cons` nil
810−-- Create a singleton stream from a pure value.
812−-- The following holds in monadic streams, but not in Zip streams:
816−-- yield = yieldM . pure
819−-- In Zip applicative streams 'yield' is not the same as 'pure' because in that
820−-- case 'pure' is equivalent to 'repeat' instead. 'yield' and 'pure' are
821−-- equally efficient, in other cases 'yield' may be slightly more efficient
822−-- than the other equivalent definitions.
826−yield :: IsStream t => a -> t m a
831−-- yieldM m = m \`consM` nil
834−-- Create a singleton stream from a monadic action.
837−-- > toList $ yieldM getLine
843−{-# INLINE yieldM #-}
844−yieldM :: (Monad m, IsStream t) => m a -> t m a
849−-- fromIndices f = let g i = f i \`cons` g (i + 1) in g 0
852−-- Generate an infinite stream, whose values are the output of a function @f@
853−-- applied on the corresponding index. Index starts at 0.
856−-- > S.toList $ S.take 5 $ S.fromIndices id
861−{-# INLINE fromIndices #-}
862−fromIndices :: (IsStream t, Monad m) => (Int -> a) -> t m a
863−fromIndices = fromStreamS . S.fromIndices
868−-- fromIndicesM f = let g i = f i \`consM` g (i + 1) in g 0
871−-- Generate an infinite stream, whose values are the output of a monadic
872−-- function @f@ applied on the corresponding index. Index starts at 0.
877−{-# INLINE_EARLY fromIndicesM #-}
878−fromIndicesM :: (IsStream t, MonadAsync m) => (Int -> m a) -> t m a
879−fromIndicesM = K.fromIndicesM
881−{-# RULES "fromIndicesM serial" fromIndicesM = fromIndicesMSerial #-}
882−{-# INLINE fromIndicesMSerial #-}
883−fromIndicesMSerial :: MonadAsync m => (Int -> m a) -> SerialT m a
884−fromIndicesMSerial = fromStreamS . S.fromIndicesM
888−-- replicateM = take n . repeatM
891−-- Generate a stream by performing a monadic action @n@ times. Same as:
894−-- drain $ serially $ S.replicateM 10 $ (threadDelay 1000000 >> print 1)
895−-- drain $ asyncly $ S.replicateM 10 $ (threadDelay 1000000 >> print 1)
901−{-# INLINE_EARLY replicateM #-}
902−replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
903−replicateM = K.replicateM
905−{-# RULES "replicateM serial" replicateM = replicateMSerial #-}
906−{-# INLINE replicateMSerial #-}
907−replicateMSerial :: MonadAsync m => Int -> m a -> SerialT m a
908−replicateMSerial n = fromStreamS . S.replicateM n
912−-- replicate = take n . repeat
915−-- Generate a stream of length @n@ by repeating a value @n@ times.
918−{-# INLINE_NORMAL replicate #-}
919−replicate :: (IsStream t, Monad m) => Int -> a -> t m a
920−replicate n = fromStreamS . S.replicate n
923−-- Generate an infinite stream by repeating a pure value.
926−{-# INLINE_NORMAL repeat #-}
927−repeat :: (IsStream t, Monad m) => a -> t m a
928−repeat = fromStreamS . S.repeat
932−-- repeatM = fix . consM
933−-- repeatM = cycle1 . yieldM
936−-- Generate a stream by repeatedly executing a monadic action forever.
939−-- drain $ serially $ S.take 10 $ S.repeatM $ (threadDelay 1000000 >> print 1)
940−-- drain $ asyncly $ S.take 10 $ S.repeatM $ (threadDelay 1000000 >> print 1)
943−-- /Concurrent, infinite (do not use with 'parallely')/
946−{-# INLINE_EARLY repeatM #-}
947−repeatM :: (IsStream t, MonadAsync m) => m a -> t m a
950−{-# RULES "repeatM serial" repeatM = repeatMSerial #-}
951−{-# INLINE repeatMSerial #-}
952−repeatMSerial :: MonadAsync m => m a -> SerialT m a
953−repeatMSerial = fromStreamS . S.repeatM
957−-- iterate f x = x \`cons` iterate f x
960−-- Generate an infinite stream with @x@ as the first element and each
961−-- successive element derived by applying the function @f@ on the previous
965−-- > S.toList $ S.take 5 $ S.iterate (+1) 1
970−{-# INLINE_NORMAL iterate #-}
971−iterate :: (IsStream t, Monad m) => (a -> a) -> a -> t m a
972−iterate step = fromStreamS . S.iterate step
976−-- iterateM f m = m >>= \a -> return a \`consM` iterateM f (f a)
979−-- Generate an infinite stream with the first element generated by the action
980−-- @m@ and each successive element derived by applying the monadic function
981−-- @f@ on the previous element.
983−-- When run concurrently, the next iteration can run concurrently with the
984−-- processing of the previous iteration. Note that more than one iteration
985−-- cannot run concurrently as the next iteration depends on the output of the
986−-- previous iteration.
989−-- drain $ serially $ S.take 10 $ S.iterateM
990−-- (\\x -> threadDelay 1000000 >> print x >> return (x + 1)) (return 0)
992−-- drain $ asyncly $ S.take 10 $ S.iterateM
993−-- (\\x -> threadDelay 1000000 >> print x >> return (x + 1)) (return 0)
1000−-- /Since: 0.7.0 (signature change)/
1001−{-# INLINE_EARLY iterateM #-}
1002−iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> m a -> t m a
1003−iterateM = K.iterateM
1005−{-# RULES "iterateM serial" iterateM = iterateMSerial #-}
1006−{-# INLINE iterateMSerial #-}
1007−iterateMSerial :: MonadAsync m => (a -> m a) -> m a -> SerialT m a
1008−iterateMSerial step = fromStreamS . S.iterateM step
1010------------------------------------------------------------------------------
657------------------------------------------------------------------------------
1011-- Conversions
658-- Conversions
1012------------------------------------------------------------------------------
659------------------------------------------------------------------------------
1016−-- fromListM = 'Prelude.foldr' 'K.consM' 'K.nil'
1019−-- Construct a stream from a list of monadic actions. This is more efficient
1020−-- than 'fromFoldableM' for serial streams.
1023−{-# INLINE_EARLY fromListM #-}
1024−fromListM :: (MonadAsync m, IsStream t) => [m a] -> t m a
1025−fromListM = fromStreamD . D.fromListM
1026−{-# RULES "fromListM fallback to StreamK" [1]
1027− forall a. D.toStreamK (D.fromListM a) = fromFoldableM a #-}
1031−-- fromFoldableM = 'Prelude.foldr' 'consM' 'K.nil'
1034−-- Construct a stream from a 'Foldable' containing monadic actions.
1037−-- drain $ serially $ S.fromFoldableM $ replicateM 10 (threadDelay 1000000 >> print 1)
1038−-- drain $ asyncly $ S.fromFoldableM $ replicateM 10 (threadDelay 1000000 >> print 1)
1041−-- /Concurrent (do not use with 'parallely' on infinite containers)/
1044−{-# INLINE fromFoldableM #-}
1045−fromFoldableM :: (IsStream t, MonadAsync m, Foldable f) => f (m a) -> t m a
1046−fromFoldableM = Prelude.foldr consM K.nil
1048−-- | Same as 'fromFoldable'.
1051−{-# DEPRECATED each "Please use fromFoldable instead." #-}
1053−each :: (IsStream t, Foldable f) => f a -> t m a
1054−each = K.fromFoldable
1056−-- | Read lines from an IO Handle into a stream of Strings.
1059−{-# DEPRECATED fromHandle
1060− "Please use Streamly.FileSystem.Handle module (see the changelog)" #-}
1061−fromHandle :: (IsStream t, MonadIO m) => IO.Handle -> t m String
1064− go = K.mkStream $ \_ yld _ stp -> do
1065− eof <- liftIO $ IO.hIsEOF h
1069− str <- liftIO $ IO.hGetLine h
1072−-- | Construct a stream by reading a 'Prim' 'IORef' repeatedly.
1076−{-# INLINE fromPrimIORef #-}
1077−fromPrimIORef :: (IsStream t, MonadIO m, Prim a) => IORef a -> t m a
1078−fromPrimIORef = fromStreamD . D.fromPrimIORef
1080-- | Takes a callback setter function and provides it with a callback. The
661-- | Takes a callback setter function and provides it with a callback. The
1081-- callback when invoked adds a value at the tail of the stream. Returns a
662-- callback when invoked adds a value at the tail of the stream. Returns a
1082-- stream of values generated by the callback.
663-- stream of values generated by the callback.
@@ -1084,3270 +665,239 @@ fromPrimIORef = fromStreamD . D.fromPrimIORef
1084-- /Internal/
665-- /Internal/
1086{-# INLINE fromCallback #-}
667{-# INLINE fromCallback #-}
1087−fromCallback :: MonadAsync m => ((a -> m ()) -> m ()) -> SerialT m a
668+fromCallback :: MonadAsync m => ((a -> m ()) -> m ()) -> SerialT m a
1088−fromCallback setCallback = concatM $ do
669+fromCallback setCallback = concatM $ do
1089− (callback, stream) <- D.newCallbackStream
670+ (callback, stream) <- D.newCallbackStream
1090− setCallback callback
671+ setCallback callback
1091− return stream
672+ return stream
1093−------------------------------------------------------------------------------
1095−------------------------------------------------------------------------------
1097−-- | @timesWith g@ returns a stream of time value tuples. The first component
1098−-- of the tuple is an absolute time reference (epoch) denoting the start of the
1099−-- stream and the second component is a time relative to the reference.
1101−-- The argument @g@ specifies the granularity of the relative time in seconds.
1102−-- A lower granularity clock gives higher precision but is more expensive in
1103−-- terms of CPU usage. Any granularity lower than 1 ms is treated as 1 ms.
1106−-- >>> S.mapM_ (\x -> print x >> threadDelay 1000000) $ S.timesWith 0.01
1107−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 0))
1108−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1002028000))
1109−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1996656000))
1112−-- Note: This API is not safe on 32-bit machines.
1116−{-# INLINE timesWith #-}
1117−timesWith :: (IsStream t, MonadAsync m) => Double -> t m (AbsTime, RelTime64)
1118−timesWith g = fromStreamD $ D.times g
1120−-- | @times@ returns a stream of time value tuples with clock of 10 ms
1121−-- granularity. The first component of the tuple is an absolute time reference
1122−-- (epoch) denoting the start of the stream and the second component is a time
1123−-- relative to the reference.
1126−-- >>> S.mapM_ (\x -> print x >> threadDelay 1000000) $ S.times
1127−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 0))
1128−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1002028000))
1129−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1996656000))
1132−-- Note: This API is not safe on 32-bit machines.
1136−{-# INLINE times #-}
1137−times :: (IsStream t, MonadAsync m) => t m (AbsTime, RelTime64)
1138−times = timesWith 0.01
1140−-- | @absTimesWith g@ returns a stream of absolute timestamps using a clock of
1141−-- granularity @g@ specified in seconds. A low granularity clock is more
1142−-- expensive in terms of CPU usage. Any granularity lower than 1 ms is treated
1146−-- >>> S.mapM_ print $ S.delayPre 1 $ S.absTimesWith 0.01
1149−-- Note: This API is not safe on 32-bit machines.
1153−{-# INLINE absTimesWith #-}
1154−absTimesWith :: (IsStream t, MonadAsync m, Functor (t m))
1155− => Double -> t m AbsTime
1156−absTimesWith = fmap (uncurry addToAbsTime64) . timesWith
1158−-- | @absTimes@ returns a stream of absolute timestamps using a clock of 10 ms
1162−-- >>> S.mapM_ print $ S.delayPre 1 $ S.absTimes
1165−-- Note: This API is not safe on 32-bit machines.
1169−{-# INLINE absTimes #-}
1170−absTimes :: (IsStream t, MonadAsync m, Functor (t m)) => t m AbsTime
1171−absTimes = fmap (uncurry addToAbsTime64) times
1173−{-# DEPRECATED currentTime "Please use absTimes instead" #-}
1174−{-# INLINE currentTime #-}
1175−currentTime :: (IsStream t, MonadAsync m, Functor (t m))
1176− => Double -> t m AbsTime
1177−currentTime = absTimesWith
1179−-- | @relTimesWith g@ returns a stream of relative time values starting from 0,
1180−-- using a clock of granularity @g@ specified in seconds. A low granularity
1181−-- clock is more expensive in terms of CPU usage. Any granularity lower than 1
1182−-- ms is treated as 1 ms.
1185−-- >>> S.mapM_ print $ S.delayPre 1 $ S.relTimesWith 0.01
1186−-- > RelTime64 (NanoSecond64 0)
1187−-- > RelTime64 (NanoSecond64 91139000)
1188−-- > RelTime64 (NanoSecond64 204052000)
1191−-- Note: This API is not safe on 32-bit machines.
1195−{-# INLINE relTimesWith #-}
1196−relTimesWith :: (IsStream t, MonadAsync m, Functor (t m))
1197− => Double -> t m RelTime64
1198−relTimesWith = fmap snd . timesWith
1200−-- | @relTimes@ returns a stream of relative time values starting from 0,
1201−-- using a clock of granularity 10 ms.
1204−-- >>> S.mapM_ print $ S.delayPre 1 $ S.relTimes
1207−-- Note: This API is not safe on 32-bit machines.
1211−{-# INLINE relTimes #-}
1212−relTimes :: (IsStream t, MonadAsync m, Functor (t m)) => t m RelTime64
1213−relTimes = fmap snd times
1215−-- | @durations g@ returns a stream of relative time values measuring the time
1216−-- elapsed since the immediate predecessor element of the stream was generated.
1217−-- The first element of the stream is always 0. @durations@ uses a clock of
1218−-- granularity @g@ specified in seconds. A low granularity clock is more
1219−-- expensive in terms of CPU usage. The minimum granularity is 1 millisecond.
1220−-- Durations lower than 1 ms will be 0.
1222−-- Note: This API is not safe on 32-bit machines.
1226−{-# INLINE durations #-}
1227−durations :: -- (IsStream t, MonadAsync m) =>
1228− Double -> t m RelTime64
1229−durations = undefined
1231−-- | Generate ticks at the specified rate. The rate is adaptive, the tick
1232−-- generation speed can be increased or decreased at different times to achieve
1233−-- the specified rate. The specific behavior for different styles of 'Rate'
1234−-- specifications is documented under 'Rate'. The effective maximum rate
1235−-- achieved by a stream is governed by the processor speed.
1239−{-# INLINE ticks #-}
1240−ticks :: -- (IsStream t, MonadAsync m) =>
1244−-- | Generate a singleton event at or after the specified absolute time. Note
1245−-- that this is different from a threadDelay, a threadDelay starts from the
1246−-- time when the action is evaluated, whereas if we use AbsTime based timeout
1247−-- it will immediately expire if the action is evaluated too late.
1251−{-# INLINE timeout #-}
1252−timeout :: -- (IsStream t, MonadAsync m) =>
1256−------------------------------------------------------------------------------
1257−-- Elimination by Folding
1258−------------------------------------------------------------------------------
1260−-- | Right associative/lazy pull fold. @foldrM build final stream@ constructs
1261−-- an output structure using the step function @build@. @build@ is invoked with
1262−-- the next input element and the remaining (lazy) tail of the output
1263−-- structure. It builds a lazy output expression using the two. When the "tail
1264−-- structure" in the output expression is evaluated it calls @build@ again thus
1265−-- lazily consuming the input @stream@ until either the output expression built
1266−-- by @build@ is free of the "tail" or the input is exhausted in which case
1267−-- @final@ is used as the terminating case for the output structure. For more
1268−-- details see the description in the previous section.
1270−-- Example, determine if any element is 'odd' in a stream:
1272−-- >>> S.foldrM (\x xs -> if odd x then return True else xs) (return False) $ S.fromList (2:4:5:undefined)
1275−-- /Since: 0.7.0 (signature changed)/
1277−-- /Since: 0.2.0 (signature changed)/
1280−{-# INLINE foldrM #-}
1281−foldrM :: Monad m => (a -> m b -> m b) -> m b -> SerialT m a -> m b
1284−-- | Right fold to a streaming monad.
1286−-- > foldrS S.cons S.nil === id
1288−-- 'foldrS' can be used to perform stateless stream to stream transformations
1289−-- like map and filter in general. It can be coupled with a scan to perform
1290−-- stateful transformations. However, note that the custom map and filter
1291−-- routines can be much more efficient than this due to better stream fusion.
1293−-- >>> S.toList $ S.foldrS S.cons S.nil $ S.fromList [1..5]
1296−-- Find if any element in the stream is 'True':
1298−-- >>> S.toList $ S.foldrS (\x xs -> if odd x then return True else xs) (return False) $ (S.fromList (2:4:5:undefined) :: SerialT IO Int)
1301−-- Map (+2) on odd elements and filter out the even elements:
1303−-- >>> S.toList $ S.foldrS (\x xs -> if odd x then (x + 2) `S.cons` xs else xs) S.nil $ (S.fromList [1..5] :: SerialT IO Int)
1306−-- 'foldrM' can also be represented in terms of 'foldrS', however, the former
1307−-- is much more efficient:
1309−-- > foldrM f z s = runIdentityT $ foldrS (\x xs -> lift $ f x (runIdentityT xs)) (lift z) s
1312−{-# INLINE foldrS #-}
1313−foldrS :: IsStream t => (a -> t m b -> t m b) -> t m b -> t m a -> t m b
1316−-- | Right fold to a transformer monad. This is the most general right fold
1317−-- function. 'foldrS' is a special case of 'foldrT', however 'foldrS'
1318−-- implementation can be more efficient:
1320−-- > foldrS = foldrT
1321−-- > foldrM f z s = runIdentityT $ foldrT (\x xs -> lift $ f x (runIdentityT xs)) (lift z) s
1323−-- 'foldrT' can be used to translate streamly streams to other transformer
1324−-- monads e.g. to a different streaming type.
1327−{-# INLINE foldrT #-}
1328−foldrT :: (IsStream t, Monad m, Monad (s m), MonadTrans s)
1329− => (a -> s m b -> s m b) -> s m b -> t m a -> s m b
1330−foldrT f z s = S.foldrT f z (toStreamS s)
1332−-- | Right fold, lazy for lazy monads and pure streams, and strict for strict
1335−-- Please avoid using this routine in strict monads like IO unless you need a
1336−-- strict right fold. This is provided only for use in lazy monads (e.g.
1337−-- Identity) or pure streams. Note that with this signature it is not possible
1338−-- to implement a lazy foldr when the monad @m@ is strict. In that case it
1339−-- would be strict in its accumulator and therefore would necessarily consume
1343−{-# INLINE foldr #-}
1344−foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
1347−-- XXX This seems to be of limited use as it cannot be used to construct
1348−-- recursive structures and for reduction foldl1' is better.
1350−-- | Lazy right fold for non-empty streams, using first element as the starting
1351−-- value. Returns 'Nothing' if the stream is empty.
1354−{-# INLINE foldr1 #-}
1355−{-# DEPRECATED foldr1 "Use foldrM instead." #-}
1356−foldr1 :: Monad m => (a -> a -> a) -> SerialT m a -> m (Maybe a)
1357−foldr1 f m = S.foldr1 f (toStreamS m)
1359−-- | Strict left fold with an extraction function. Like the standard strict
1360−-- left fold, but applies a user supplied extraction function (the third
1361−-- argument) to the folded value at the end. This is designed to work with the
1362−-- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
1365−{-# DEPRECATED foldx "Please use foldl' followed by fmap instead." #-}
1366−{-# INLINE foldx #-}
1367−foldx :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
1370−-- | Left associative/strict push fold. @foldl' reduce initial stream@ invokes
1371−-- @reduce@ with the accumulator and the next input in the input stream, using
1372−-- @initial@ as the initial value of the current value of the accumulator. When
1373−-- the input is exhausted the current value of the accumulator is returned.
1374−-- Make sure to use a strict data structure for accumulator to not build
1375−-- unnecessary lazy expressions unless that's what you want. See the previous
1376−-- section for more details.
1379−{-# INLINE foldl' #-}
1380−foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
1383−-- | Strict left fold, for non-empty streams, using first element as the
1384−-- starting value. Returns 'Nothing' if the stream is empty.
1387−{-# INLINE foldl1' #-}
1388−foldl1' :: Monad m => (a -> a -> a) -> SerialT m a -> m (Maybe a)
1392− Nothing -> return Nothing
1394− res <- foldl' step h t
1397−-- | Like 'foldx', but with a monadic step function.
1400−{-# DEPRECATED foldxM "Please use foldlM' followed by fmap instead." #-}
1401−{-# INLINE foldxM #-}
1402−foldxM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
1405−-- | Like 'foldl'' but with a monadic step function.
1409−-- /Since: 0.8.0 (signature change)/
1410−{-# INLINE foldlM' #-}
1411−foldlM' :: Monad m => (b -> a -> m b) -> m b -> SerialT m a -> m b
1412−foldlM' step begin m = S.foldlM' step begin $ toStreamS m
1414−------------------------------------------------------------------------------
1416−------------------------------------------------------------------------------
1418−-- | Fold a stream using the supplied left 'Fold' and reducing the resulting
1419−-- expression strictly at each step. The behavior is similar to 'foldl''. A
1420−-- 'Fold' can terminate early without consuming the full stream. See the
1421−-- documentation of individual 'Fold's for termination behavior.
1423−-- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
1428−fold :: Monad m => Fold m a b -> SerialT m a -> m b
1431−------------------------------------------------------------------------------
1433−------------------------------------------------------------------------------
1436−-- | Drain a stream to a 'Sink'.
1437−{-# INLINE runSink #-}
1438−runSink :: Monad m => Sink m a -> SerialT m a -> m ()
1439−runSink = fold . toFold
1442−------------------------------------------------------------------------------
1444−------------------------------------------------------------------------------
1446−-- | Parse a stream using the supplied 'Parser'.
1450−{-# INLINE_NORMAL parseD #-}
1451−parseD :: MonadThrow m => PRD.Parser m a b -> SerialT m a -> m b
1452−parseD (PRD.Parser step initial extract) = P.parselMx' step initial extract
1454−{-# INLINE parseK #-}
1455−parseK :: MonadThrow m => PRK.Parser m a b -> SerialT m a -> m b
1458−-- | Parse a stream using the supplied 'Parser'.
1462−{-# INLINE [3] parse #-}
1463−parse :: MonadThrow m => Parser m a b -> SerialT m a -> m b
1464−parse = parseD . PRK.fromParserK
1466−------------------------------------------------------------------------------
1467−-- Specialized folds
1468−------------------------------------------------------------------------------
1471−-- > drain = mapM_ (\_ -> return ())
1472−-- > drain = fold Fold.drain
1474−-- Run a stream, discarding the results. By default it interprets the stream
1475−-- as 'SerialT', to run other types of streams use the type adapting
1476−-- combinators for example @drain . 'asyncly'@.
1479−{-# INLINE drain #-}
1480−drain :: Monad m => SerialT m a -> m ()
1483−-- | Run a stream, discarding the results. By default it interprets the stream
1484−-- as 'SerialT', to run other types of streams use the type adapting
1485−-- combinators for example @runStream . 'asyncly'@.
1488−{-# DEPRECATED runStream "Please use \"drain\" instead" #-}
1489−{-# INLINE runStream #-}
1490−runStream :: Monad m => SerialT m a -> m ()
1494−-- > drainN n = drain . take n
1495−-- > drainN n = fold (Fold.ltake n Fold.drain)
1497−-- Run maximum up to @n@ iterations of a stream.
1500−{-# INLINE drainN #-}
1501−drainN :: Monad m => Int -> SerialT m a -> m ()
1502−drainN n = drain . take n
1505−-- > runN n = runStream . take n
1507−-- Run maximum up to @n@ iterations of a stream.
1510−{-# DEPRECATED runN "Please use \"drainN\" instead" #-}
1512−runN :: Monad m => Int -> SerialT m a -> m ()
1516−-- > drainWhile p = drain . takeWhile p
1517−-- > drainWhile p = fold (Fold.sliceSepBy (not . p) Fold.drain)
1519−-- Run a stream as long as the predicate holds true.
1522−{-# INLINE drainWhile #-}
1523−drainWhile :: Monad m => (a -> Bool) -> SerialT m a -> m ()
1524−drainWhile p = drain . takeWhile p
1527−-- > runWhile p = runStream . takeWhile p
1529−-- Run a stream as long as the predicate holds true.
1532−{-# DEPRECATED runWhile "Please use \"drainWhile\" instead" #-}
1533−{-# INLINE runWhile #-}
1534−runWhile :: Monad m => (a -> Bool) -> SerialT m a -> m ()
1535−runWhile = drainWhile
1537−-- | Determine whether the stream is empty.
1539−-- > null = fold Fold.null
1543−null :: Monad m => SerialT m a -> m Bool
1544−null = S.null . toStreamS
1546−-- | Extract the first element of the stream, if any.
1549−-- > head = fold Fold.head
1553−head :: Monad m => SerialT m a -> m (Maybe a)
1554−head = S.head . toStreamS
1556−-- | Extract the first element of the stream, if any, otherwise use the
1557−-- supplied default value. It can help avoid one branch in high performance
1561−{-# INLINE headElse #-}
1562−headElse :: Monad m => a -> SerialT m a -> m a
1563−headElse x = D.headElse x . toStreamD
1566−-- > tail = fmap (fmap snd) . uncons
1568−-- Extract all but the first element of the stream, if any.
1572−tail :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
1573−tail m = K.tail (K.adapt m)
1575−-- | Extract all but the last element of the stream, if any.
1579−init :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
1580−init m = K.init (K.adapt m)
1582−-- | Extract the last element of the stream, if any.
1584−-- > last xs = xs !! (length xs - 1)
1585−-- > last = fold Fold.last
1589−last :: Monad m => SerialT m a -> m (Maybe a)
1590−last m = S.last $ toStreamS m
1592−-- | Determine whether an element is present in the stream.
1594−-- > elem = fold Fold.elem
1598−elem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
1599−elem e m = S.elem e (toStreamS m)
1601−-- | Determine whether an element is not present in the stream.
1603−-- > notElem = fold Fold.notElem
1606−{-# INLINE notElem #-}
1607−notElem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
1608−notElem e m = S.notElem e (toStreamS m)
1610−-- | Determine the length of the stream.
1612−-- > notElem = fold Fold.length
1615−{-# INLINE length #-}
1616−length :: Monad m => SerialT m a -> m Int
1617−length = foldl' (\n _ -> n + 1) 0
1619−-- | Determine whether all elements of a stream satisfy a predicate.
1621−-- > all = fold Fold.all
1625−all :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
1626−all p m = S.all p (toStreamS m)
1628−-- | Determine whether any of the elements of a stream satisfy a predicate.
1630−-- > any = fold Fold.any
1634−any :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
1635−any p m = S.any p (toStreamS m)
1637−-- | Determines if all elements of a boolean stream are True.
1639−-- > and = fold Fold.and
1643−and :: Monad m => SerialT m Bool -> m Bool
1646−-- | Determines whether at least one element of a boolean stream is True.
1648−-- > or = fold Fold.or
1652−or :: Monad m => SerialT m Bool -> m Bool
1655−-- | Determine the sum of all elements of a stream of numbers. Returns @0@ when
1656−-- the stream is empty. Note that this is not numerically stable for floating
1659−-- > sum = fold Fold.sum
1663−sum :: (Monad m, Num a) => SerialT m a -> m a
1666−-- | Determine the product of all elements of a stream of numbers. Returns @1@
1667−-- when the stream is empty.
1669−-- > product = fold Fold.product
1672−{-# INLINE product #-}
1673−product :: (Monad m, Num a) => SerialT m a -> m a
1674−product = foldl' (*) 1
1676−-- | Fold a stream of monoid elements by appending them.
1678−-- > mconcat = fold Fold.mconcat
1681−{-# INLINE mconcat #-}
1682−mconcat :: (Monad m, Monoid a) => SerialT m a -> m a
1683−mconcat = foldr mappend mempty
1687−-- minimum = 'minimumBy' compare
1688−-- minimum = fold Fold.minimum
1691−-- Determine the minimum element in a stream.
1694−{-# INLINE minimum #-}
1695−minimum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
1696−minimum m = S.minimum (toStreamS m)
1698−-- | Determine the minimum element in a stream using the supplied comparison
1701−-- > minimumBy = fold Fold.minimumBy
1704−{-# INLINE minimumBy #-}
1705−minimumBy :: Monad m => (a -> a -> Ordering) -> SerialT m a -> m (Maybe a)
1706−minimumBy cmp m = S.minimumBy cmp (toStreamS m)
1710−-- maximum = 'maximumBy' compare
1711−-- maximum = fold Fold.maximum
1714−-- Determine the maximum element in a stream.
1717−{-# INLINE maximum #-}
1718−maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
1721−-- | Determine the maximum element in a stream using the supplied comparison
1724−-- > maximumBy = fold Fold.maximumBy
1727−{-# INLINE maximumBy #-}
1728−maximumBy :: Monad m => (a -> a -> Ordering) -> SerialT m a -> m (Maybe a)
1729−maximumBy cmp m = S.maximumBy cmp (toStreamS m)
1731−-- | Lookup the element at the given index.
1735−(!!) :: Monad m => SerialT m a -> Int -> m (Maybe a)
1736−m !! i = toStreamS m S.!! i
1738−-- | In a stream of (key-value) pairs @(a, b)@, return the value @b@ of the
1739−-- first pair where the key equals the given value @a@.
1741−-- > lookup = snd <$> find ((==) . fst)
1742−-- > lookup = fold Fold.lookup
1745−{-# INLINE lookup #-}
1746−lookup :: (Monad m, Eq a) => a -> SerialT m (a, b) -> m (Maybe b)
1747−lookup a m = S.lookup a (toStreamS m)
1749−-- | Like 'findM' but with a non-monadic predicate.
1751−-- > find p = findM (return . p)
1752−-- > find = fold Fold.find
1756−find :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe a)
1757−find p m = S.find p (toStreamS m)
1759−-- | Returns the first element that satisfies the given predicate.
1761−-- > findM = fold Fold.findM
1764−{-# INLINE findM #-}
1765−findM :: Monad m => (a -> m Bool) -> SerialT m a -> m (Maybe a)
1766−findM p m = S.findM p (toStreamS m)
1768−-- | Find all the indices where the element in the stream satisfies the given
1771−-- > findIndices = fold Fold.findIndices
1774−{-# INLINE findIndices #-}
1775−findIndices :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m Int
1776−findIndices p m = fromStreamS $ S.findIndices p (toStreamS m)
1778−-- | Returns the first index that satisfies the given predicate.
1780−-- > findIndex = fold Fold.findIndex
1783−{-# INLINE findIndex #-}
1784−findIndex :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe Int)
1785−findIndex p = head . findIndices p
1787−-- | Find all the indices where the value of the element in the stream is equal
1788−-- to the given value.
1790−-- > elemIndices a = findIndices (== a)
1793−{-# INLINE elemIndices #-}
1794−elemIndices :: (IsStream t, Eq a, Monad m) => a -> t m a -> t m Int
1795−elemIndices a = findIndices (== a)
1797−-- | Returns the first index where a given value is found in the stream.
1799−-- > elemIndex a = findIndex (== a)
1802−{-# INLINE elemIndex #-}
1803−elemIndex :: (Monad m, Eq a) => a -> SerialT m a -> m (Maybe Int)
1804−elemIndex a = findIndex (== a)
1806−------------------------------------------------------------------------------
1808−------------------------------------------------------------------------------
1810−-- | Returns 'True' if the first stream is the same as or a prefix of the
1811−-- second. A stream is a prefix of itself.
1814−-- > S.isPrefixOf (S.fromList "hello") (S.fromList "hello" :: SerialT IO Char)
1819−{-# INLINE isPrefixOf #-}
1820−isPrefixOf :: (Eq a, IsStream t, Monad m) => t m a -> t m a -> m Bool
1821−isPrefixOf m1 m2 = D.isPrefixOf (toStreamD m1) (toStreamD m2)
1823−-- Note: isPrefixOf uses the prefix stream only once. In contrast, isSuffixOf
1824−-- may use the suffix stream many times. To run in optimal memory we do not
1825−-- want to buffer the suffix stream in memory therefore we need an ability to
1826−-- clone (or consume it multiple times) the suffix stream without any side
1827−-- effects so that multiple potential suffix matches can proceed in parallel
1828−-- without buffering the suffix stream. For example, we may create the suffix
1829−-- stream from a file handle, however, if we evaluate the stream multiple
1830−-- times, once for each match, we will need a different file handle each time
1831−-- which may exhaust the file descriptors. Instead, we want to share the same
1832−-- underlying file descriptor, use pread on it to generate the stream and clone
1833−-- the stream for each match. Therefore the suffix stream should be built in
1834−-- such a way that it can be consumed multiple times without any problems.
1836−-- XXX Can be implemented with better space/time complexity.
1837−-- Space: @O(n)@ worst case where @n@ is the length of the suffix.
1839−-- | Returns 'True' if the first stream is a suffix of the second. A stream is
1840−-- considered a suffix of itself.
1843−-- > S.isSuffixOf (S.fromList "hello") (S.fromList "hello" :: SerialT IO Char)
1847−-- Space: @O(n)@, buffers entire input stream and the suffix.
1851−-- /Suboptimal/ - Help wanted.
1853−{-# INLINE isSuffixOf #-}
1854−isSuffixOf :: (Monad m, Eq a) => SerialT m a -> SerialT m a -> m Bool
1855−isSuffixOf suffix stream = reverse suffix `isPrefixOf` reverse stream
1857−-- | Returns 'True' if the first stream is an infix of the second. A stream is
1858−-- considered an infix of itself.
1861−-- > S.isInfixOf (S.fromList "hello") (S.fromList "hello" :: SerialT IO Char)
1865−-- Space: @O(n)@ worst case where @n@ is the length of the infix.
1869−-- /Requires 'Storable' constraint/ - Help wanted.
1871−{-# INLINE isInfixOf #-}
1872−isInfixOf :: (MonadIO m, Eq a, Enum a, Storable a)
1873− => SerialT m a -> SerialT m a -> m Bool
1874−isInfixOf infx stream = do
1875− arr <- fold A.write infx
1876− -- XXX can use breakOnSeq instead (when available)
1877− r <- null $ drop 1 $ splitOnSeq arr FL.drain stream
1880−-- | Returns 'True' if all the elements of the first stream occur, in order, in
1881−-- the second stream. The elements do not have to occur consecutively. A stream
1882−-- is a subsequence of itself.
1885−-- > S.isSubsequenceOf (S.fromList "hlo") (S.fromList "hello" :: SerialT IO Char)
1890−{-# INLINE isSubsequenceOf #-}
1891−isSubsequenceOf :: (Eq a, IsStream t, Monad m) => t m a -> t m a -> m Bool
1892−isSubsequenceOf m1 m2 = D.isSubsequenceOf (toStreamD m1) (toStreamD m2)
1894−-- | @stripPrefix prefix stream@ strips @prefix@ from @stream@ if it is a
1895−-- prefix of stream. Returns 'Nothing' if the stream does not start with the
1896−-- given prefix, stripped stream otherwise. Returns @Just nil@ when the prefix
1897−-- is the same as the stream.
1902−{-# INLINE stripPrefix #-}
1904− :: (Eq a, IsStream t, Monad m)
1905− => t m a -> t m a -> m (Maybe (t m a))
1906−stripPrefix m1 m2 = fmap fromStreamD <$>
1907− D.stripPrefix (toStreamD m1) (toStreamD m2)
1909−-- Note: If we want to return a Maybe value to know whether the
1910−-- suffix/infix was present or not along with the stripped stream then
1911−-- we need to buffer the whole input stream.
1913−-- | Drops the given suffix from a stream. Returns 'Nothing' if the stream does
1914−-- not end with the given suffix. Returns @Just nil@ when the suffix is the
1915−-- same as the stream.
1917−-- It may be more efficient to convert the stream to an Array and use
1918−-- stripSuffix on that especially if the elements have a Storable or Prim
1921−-- Space: @O(n)@, buffers the entire input stream as well as the suffix
1924−{-# INLINE stripSuffix #-}
1927− => SerialT m a -> SerialT m a -> m (Maybe (SerialT m a))
1928−stripSuffix m1 m2 = fmap reverse <$> stripPrefix (reverse m1) (reverse m2)
1930−-- | Drop prefix from the input stream if present.
1934−-- /Unimplemented/ - Help wanted.
1935−{-# INLINE dropPrefix #-}
1937− -- (Eq a, IsStream t, Monad m) =>
1938− t m a -> t m a -> t m a
1939−dropPrefix = error "Not implemented yet!"
1941−-- | Drop all matching infix from the input stream if present. Infix stream
1942−-- may be consumed multiple times.
1944−-- Space: @O(n)@ where n is the length of the infix.
1946−-- /Unimplemented/ - Help wanted.
1947−{-# INLINE dropInfix #-}
1949− -- (Eq a, IsStream t, Monad m) =>
1950− t m a -> t m a -> t m a
1951−dropInfix = error "Not implemented yet!"
1953−-- | Drop suffix from the input stream if present. Suffix stream may be
1954−-- consumed multiple times.
1956−-- Space: @O(n)@ where n is the length of the suffix.
1958−-- /Unimplemented/ - Help wanted.
1959−{-# INLINE dropSuffix #-}
1961− -- (Eq a, IsStream t, Monad m) =>
1962− t m a -> t m a -> t m a
1963−dropSuffix = error "Not implemented yet!"
1965−------------------------------------------------------------------------------
1967−------------------------------------------------------------------------------
1969−-- XXX this can utilize parallel mapping if we implement it as drain . mapM
1971−-- > mapM_ = drain . mapM
1973−-- Apply a monadic action to each element of the stream and discard the output
1974−-- of the action. This is not really a pure transformation operation but a
1975−-- transformation followed by fold.
1978−{-# INLINE mapM_ #-}
1979−mapM_ :: Monad m => (a -> m b) -> SerialT m a -> m ()
1980−mapM_ f m = S.mapM_ f $ toStreamS m
1982−------------------------------------------------------------------------------
1984−------------------------------------------------------------------------------
1988−-- toList = S.foldr (:) []
1991−-- Convert a stream into a list in the underlying monad. The list can be
1992−-- consumed lazily in a lazy monad (e.g. 'Identity'). In a strict monad (e.g.
1993−-- IO) the whole list is generated and buffered before it can be consumed.
1995−-- /Warning!/ working on large lists accumulated as buffers in memory could be
1996−-- very inefficient, consider using "Streamly.Array" instead.
1999−{-# INLINE toList #-}
2000−toList :: Monad m => SerialT m a -> m [a]
2005−-- toListRev = S.foldl' (flip (:)) []
2008−-- Convert a stream into a list in reverse order in the underlying monad.
2010−-- /Warning!/ working on large lists accumulated as buffers in memory could be
2011−-- very inefficient, consider using "Streamly.Array" instead.
2014−{-# INLINE toListRev #-}
2015−toListRev :: Monad m => SerialT m a -> m [a]
2016−toListRev = D.toListRev . toStreamD
2020−-- toHandle h = S.mapM_ $ hPutStrLn h
2023−-- Write a stream of Strings to an IO Handle.
2026−{-# DEPRECATED toHandle
2027− "Please use Streamly.FileSystem.Handle module (see the changelog)" #-}
2028−toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
2032− let stop = return ()
2033− single a = liftIO (IO.hPutStrLn h a)
2034− yieldk a r = liftIO (IO.hPutStrLn h a) >> go r
2035− in K.foldStream defState yieldk single stop m1
2037−-- XXX rename these to write/writeRev to make the naming consistent with folds
2038−-- in other modules.
2040−-- | A fold that buffers its input to a pure stream.
2042−-- /Warning!/ working on large streams accumulated as buffers in memory could
2043−-- be very inefficient, consider using "Streamly.Data.Array" instead.
2046−{-# INLINE toStream #-}
2047−toStream :: Monad m => Fold m a (SerialT Identity a)
2048−toStream = Fold (\f x -> return $ FL.Partial $ f . (x `K.cons`))
2050− (return . ($ K.nil))
2052−-- This is more efficient than 'toStream'. toStream is exactly the same as
2053−-- reversing the stream after toStreamRev.
2055−-- | Buffers the input stream to a pure stream in the reverse order of the
2058−-- /Warning!/ working on large streams accumulated as buffers in memory could
2059−-- be very inefficient, consider using "Streamly.Data.Array" instead.
2063−-- xn : ... : x2 : x1 : []
2064−{-# INLINABLE toStreamRev #-}
2065−toStreamRev :: Monad m => Fold m a (SerialT Identity a)
2066−toStreamRev = Fold (\xs x -> return $ FL.Partial $ x `K.cons` xs) (return K.nil) return
2068−-- | Convert a stream to a pure stream.
2071−-- toPure = foldr cons nil
2076−{-# INLINE toPure #-}
2077−toPure :: Monad m => SerialT m a -> m (SerialT Identity a)
2078−toPure = foldr K.cons K.nil
2080−-- | Convert a stream to a pure stream in reverse order.
2083−-- toPureRev = foldl' (flip cons) nil
2088−{-# INLINE toPureRev #-}
2089−toPureRev :: Monad m => SerialT m a -> m (SerialT Identity a)
2090−toPureRev = foldl' (flip K.cons) K.nil
2092−------------------------------------------------------------------------------
2093−-- Concurrent Application
2094−------------------------------------------------------------------------------
2102−-- | Parallel transform application operator; applies a stream transformation
2103−-- function @t m a -> t m b@ to a stream @t m a@ concurrently; the input stream
2104−-- is evaluated asynchronously in an independent thread yielding elements to a
2105−-- buffer and the transformation function runs in another thread consuming the
2106−-- input from the buffer. '|$' is just like regular function application
2107−-- operator '$' except that it is concurrent.
2109−-- If you read the signature as @(t m a -> t m b) -> (t m a -> t m b)@ you can
2110−-- look at it as a transformation that converts a transform function to a
2111−-- buffered concurrent transform function.
2113−-- The following code prints a value every second even though each stage adds a
2119−-- S.mapM (\\x -> threadDelay 1000000 >> print x)
2120−-- |$ S.repeatM (threadDelay 1000000 >> return 1)
2125−-- /Since: 0.3.0 ("Streamly")/
2129−(|$) :: (IsStream t, MonadAsync m) => (t m a -> t m b) -> (t m a -> t m b)
2130−-- (|$) f = f . Async.mkAsync
2131−(|$) f = f . D.mkParallel
2137−{-# INLINE applyAsync #-}
2138−applyAsync :: (IsStream t, MonadAsync m)
2139− => (t m a -> t m b) -> (t m a -> t m b)
2142−-- | Parallel reverse function application operator for streams; just like the
2143−-- regular reverse function application operator '&' except that it is
2148−-- S.repeatM (threadDelay 1000000 >> return 1)
2149−-- |& S.mapM (\\x -> threadDelay 1000000 >> print x)
2154−-- /Since: 0.3.0 ("Streamly")/
2158−(|&) :: (IsStream t, MonadAsync m) => t m a -> (t m a -> t m b) -> t m b
2161−-- | Parallel fold application operator; applies a fold function @t m a -> m b@
2162−-- to a stream @t m a@ concurrently; The the input stream is evaluated
2163−-- asynchronously in an independent thread yielding elements to a buffer and
2164−-- the folding action runs in another thread consuming the input from the
2167−-- If you read the signature as @(t m a -> m b) -> (t m a -> m b)@ you can look
2168−-- at it as a transformation that converts a fold function to a buffered
2169−-- concurrent fold function.
2171−-- The @.@ at the end of the operator is a mnemonic for termination of the
2175−-- S.foldlM' (\\_ a -> threadDelay 1000000 >> print a) ()
2176−-- |$. S.repeatM (threadDelay 1000000 >> return 1)
2181−-- /Since: 0.3.0 ("Streamly")/
2184−{-# INLINE (|$.) #-}
2185−(|$.) :: (IsStream t, MonadAsync m) => (t m a -> m b) -> (t m a -> m b)
2186−-- (|$.) f = f . Async.mkAsync
2187−(|$.) f = f . D.mkParallel
2193−{-# INLINE foldAsync #-}
2194−foldAsync :: (IsStream t, MonadAsync m) => (t m a -> m b) -> (t m a -> m b)
2197−-- | Parallel reverse function application operator for applying a run or fold
2198−-- functions to a stream. Just like '|$.' except that the operands are reversed.
2201−-- S.repeatM (threadDelay 1000000 >> return 1)
2202−-- |&. S.foldlM' (\\_ a -> threadDelay 1000000 >> print a) ()
2207−-- /Since: 0.3.0 ("Streamly")/
2210−{-# INLINE (|&.) #-}
2211−(|&.) :: (IsStream t, MonadAsync m) => t m a -> (t m a -> m b) -> m b
2214−------------------------------------------------------------------------------
2215−-- General Transformation
2216−------------------------------------------------------------------------------
2218−-- | Use a 'Pipe' to transform a stream.
2222−{-# INLINE transform #-}
2223−transform :: (IsStream t, Monad m) => Pipe m a b -> t m a -> t m b
2224−transform pipe xs = fromStreamD $ D.transform pipe (toStreamD xs)
2226−------------------------------------------------------------------------------
2227−-- Transformation by Folding (Scans)
2228−------------------------------------------------------------------------------
2230−-- XXX It may be useful to have a version of scan where we can keep the
2231−-- accumulator independent of the value emitted. So that we do not necessarily
2232−-- have to keep a value in the accumulator which we are not using. We can pass
2233−-- an extraction function that will take the accumulator and the current value
2234−-- of the element and emit the next value in the stream. That will also make it
2235−-- possible to modify the accumulator after using it. In fact, the step function
2236−-- can return new accumulator and the value to be emitted. The signature would
2237−-- be more like mapAccumL. Or we can change the signature of scanx to
2238−-- accommodate this.
2240−-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
2241−-- user supplied extraction function (the third argument) at each step. This is
2242−-- designed to work with the @foldl@ library. The suffix @x@ is a mnemonic for
2247−-- /Since: 0.7.0 (Monad m constraint)/
2248−{-# DEPRECATED scanx "Please use scanl followed by map instead." #-}
2249−{-# INLINE scanx #-}
2250−scanx :: (IsStream t, Monad m) => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
2253−-- XXX this needs to be concurrent
2254−-- XXX because of the use of D.cons for appending, scanlM' has quadratic
2255−-- complexity when iterated over a stream. We should use StreamK style scanlM'
2256−-- for linear performance on iteration.
2258−-- | Like 'scanl'' but with a monadic step function and a monadic seed.
2262−-- /Since: 0.8.0 (signature change)/
2263−{-# INLINE scanlM' #-}
2264−scanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> m b -> t m a -> t m b
2265−scanlM' step begin m = fromStreamD $ D.scanlM' step begin $ toStreamD m
2267−-- | @scanlMAfter' accumulate initial done stream@ is like 'scanlM'' except
2268−-- that it provides an additional @done@ function to be applied on the
2269−-- accumulator when the stream stops. The result of @done@ is also emitted in
2272−-- This function can be used to allocate a resource in the beginning of the
2273−-- scan and release it when the stream ends or to flush the internal state of
2274−-- the scan at the end.
2278−{-# INLINE scanlMAfter' #-}
2279−scanlMAfter' :: (IsStream t, Monad m)
2280− => (b -> a -> m b) -> m b -> (b -> m b) -> t m a -> t m b
2281−scanlMAfter' step initial done stream =
2282− fromStreamD $ D.scanlMAfter' step initial done $ toStreamD stream
2284−-- XXX because of the use of D.cons for appending, scanl' has quadratic
2285−-- complexity when iterated over a stream. We should use StreamK style scanlM'
2286−-- for linear performance on iteration.
2288−-- | Strict left scan. Like 'map', 'scanl'' too is a one to one transformation,
2289−-- however it adds an extra element.
2292−-- > S.toList $ S.scanl' (+) 0 $ fromList [1,2,3,4]
2297−-- > S.toList $ S.scanl' (flip (:)) [] $ S.fromList [1,2,3,4]
2298−-- [[],[1],[2,1],[3,2,1],[4,3,2,1]]
2301−-- The output of 'scanl'' is the initial value of the accumulator followed by
2302−-- all the intermediate steps and the final result of 'foldl''.
2304−-- By streaming the accumulated state after each fold step, we can share the
2305−-- state across multiple stages of stream composition. Each stage can modify or
2306−-- extend the state, do some processing with it and emit it for the next stage,
2307−-- thus modularizing the stream processing. This can be useful in
2308−-- stateful or event-driven programming.
2310−-- Consider the following monolithic example, computing the sum and the product
2311−-- of the elements in a stream in one go using a @foldl'@:
2314−-- > S.foldl' (\\(s, p) x -> (s + x, p * x)) (0,1) $ S.fromList \[1,2,3,4]
2318−-- Using @scanl'@ we can make it modular by computing the sum in the first
2319−-- stage and passing it down to the next stage for computing the product:
2322−-- > S.foldl' (\\(_, p) (s, x) -> (s, p * x)) (0,1)
2323−-- $ S.scanl' (\\(s, _) x -> (s + x, x)) (0,1)
2324−-- $ S.fromList \[1,2,3,4]
2328−-- IMPORTANT: 'scanl'' evaluates the accumulator to WHNF. To avoid building
2329−-- lazy expressions inside the accumulator, it is recommended that a strict
2330−-- data structure is used for accumulator.
2332−-- See also: 'usingStateT'
2335−{-# INLINE scanl' #-}
2336−scanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
2337−scanl' step z m = fromStreamS $ S.scanl' step z $ toStreamS m
2339−-- | Like 'scanl'' but does not stream the initial value of the accumulator.
2341−-- > postscanl' f z xs = S.drop 1 $ S.scanl' f z xs
2344−{-# INLINE postscanl' #-}
2345−postscanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
2346−postscanl' step z m = fromStreamD $ D.postscanl' step z $ toStreamD m
2348−-- XXX this needs to be concurrent
2349−-- | Like 'postscanl'' but with a monadic step function and a monadic seed.
2353−-- /Since: 0.8.0 (signature change)/
2354−{-# INLINE postscanlM' #-}
2355−postscanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> m b -> t m a -> t m b
2356−postscanlM' step z m = fromStreamD $ D.postscanlM' step z $ toStreamD m
2358−-- XXX prescanl does not sound very useful, enable only if there is a
2359−-- compelling use case.
2361−-- | Like scanl' but does not stream the final value of the accumulator.
2364−{-# INLINE prescanl' #-}
2365−prescanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
2366−prescanl' step z m = fromStreamD $ D.prescanl' step z $ toStreamD m
2368−-- XXX this needs to be concurrent
2369−-- | Like prescanl' but with a monadic step function and a monadic seed.
2372−{-# INLINE prescanlM' #-}
2373−prescanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> m b -> t m a -> t m b
2374−prescanlM' step z m = fromStreamD $ D.prescanlM' step z $ toStreamD m
2376−-- XXX this needs to be concurrent
2377−-- | Like 'scanl1'' but with a monadic step function.
2380−{-# INLINE scanl1M' #-}
2381−scanl1M' :: (IsStream t, Monad m) => (a -> a -> m a) -> t m a -> t m a
2382−scanl1M' step m = fromStreamD $ D.scanl1M' step $ toStreamD m
2384−-- | Like 'scanl'' but for a non-empty stream. The first element of the stream
2385−-- is used as the initial value of the accumulator. Does nothing if the stream
2389−-- > S.toList $ S.scanl1 (+) $ fromList [1,2,3,4]
2394−{-# INLINE scanl1' #-}
2395−scanl1' :: (IsStream t, Monad m) => (a -> a -> a) -> t m a -> t m a
2396−scanl1' step m = fromStreamD $ D.scanl1' step $ toStreamD m
2398−------------------------------------------------------------------------------
2399−-- Scanning with a Fold
2400−------------------------------------------------------------------------------
2402−-- | Scan a stream using the given monadic fold.
2406−scan :: (IsStream t, Monad m) => Fold m a b -> t m a -> t m b
2409−-- | Postscan a stream using the given monadic fold.
2412−{-# INLINE postscan #-}
2413−postscan :: (IsStream t, Monad m) => Fold m a b -> t m a -> t m b
2414−postscan = P.postscanOnce
2416−------------------------------------------------------------------------------
2417−-- Stateful Transformations
2418−------------------------------------------------------------------------------
2420−-- XXX this is not a one-to-one map so calling it map may not be right.
2421−-- We can perhaps call it zipWithTail or rollWith.
2423−-- | Apply a function on every two successive elements of a stream. If the
2424−-- stream consists of a single element the output is an empty stream.
2426−-- This is the stream equivalent of the list idiom @zipWith f xs (tail xs)@.
2430−{-# INLINE rollingMap #-}
2431−rollingMap :: (IsStream t, Monad m) => (a -> a -> b) -> t m a -> t m b
2432−rollingMap f m = fromStreamD $ D.rollingMap f $ toStreamD m
2434−-- | Like 'rollingMap' but with an effectful map function.
2438−{-# INLINE rollingMapM #-}
2439−rollingMapM :: (IsStream t, Monad m) => (a -> a -> m b) -> t m a -> t m b
2440−rollingMapM f m = fromStreamD $ D.rollingMapM f $ toStreamD m
2442−------------------------------------------------------------------------------
2443−-- Transformation by Filtering
2444−------------------------------------------------------------------------------
2446−-- | Include only those elements that pass a predicate.
2449−{-# INLINE filter #-}
2450−#if __GLASGOW_HASKELL__ != 802
2451−-- GHC 8.2.2 crashes with this code, when used with "stack"
2452−filter :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m a
2453−filter p m = fromStreamS $ S.filter p $ toStreamS m
2455−filter :: IsStream t => (a -> Bool) -> t m a -> t m a
2459−-- | Same as 'filter' but with a monadic predicate.
2462−{-# INLINE filterM #-}
2463−filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a
2464−filterM p m = fromStreamD $ D.filterM p $ toStreamD m
2466−-- | Drop repeated elements that are adjacent to each other.
2470−uniq :: (Eq a, IsStream t, Monad m) => t m a -> t m a
2471−uniq = fromStreamD . D.uniq . toStreamD
2473−-- | Ensures that all the elements of the stream are identical and then returns
2474−-- that unique element.
2478−the :: (Eq a, Monad m) => SerialT m a -> m (Maybe a)
2479−the m = S.the (toStreamS m)
2481−-- | Take first 'n' elements from the stream and discard the rest.
2485−take :: (IsStream t, Monad m) => Int -> t m a -> t m a
2486−take n m = fromStreamS $ S.take n $ toStreamS
2487− (maxYields (Just (fromIntegral n)) m)
2489−-- | End the stream as soon as the predicate fails on an element.
2492−{-# INLINE takeWhile #-}
2493−takeWhile :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m a
2494−takeWhile p m = fromStreamS $ S.takeWhile p $ toStreamS m
2496−-- | Same as 'takeWhile' but with a monadic predicate.
2499−{-# INLINE takeWhileM #-}
2500−takeWhileM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a
2501−takeWhileM p m = fromStreamD $ D.takeWhileM p $ toStreamD m
2503−-- | @takeByTime duration@ yields stream elements upto specified time
2504−-- @duration@. The duration starts when the stream is evaluated for the first
2505−-- time, before the first element is yielded. The time duration is checked
2506−-- before generating each element, if the duration has expired the stream
2509−-- The total time taken in executing the stream is guaranteed to be /at least/
2510−-- @duration@, however, because the duration is checked before generating an
2511−-- element, the upper bound is indeterminate and depends on the time taken in
2512−-- generating and processing the last element.
2514−-- No element is yielded if the duration is zero. At least one element is
2515−-- yielded if the duration is non-zero.
2519−{-# INLINE takeByTime #-}
2520−takeByTime ::(MonadIO m, IsStream t, TimeUnit64 d) => d -> t m a -> t m a
2521−takeByTime d = fromStreamD . D.takeByTime d . toStreamD
2523−-- | Discard first 'n' elements from the stream and take the rest.
2527−drop :: (IsStream t, Monad m) => Int -> t m a -> t m a
2528−drop n m = fromStreamS $ S.drop n $ toStreamS m
2530−-- | Drop elements in the stream as long as the predicate succeeds and then
2531−-- take the rest of the stream.
2534−{-# INLINE dropWhile #-}
2535−dropWhile :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m a
2536−dropWhile p m = fromStreamS $ S.dropWhile p $ toStreamS m
2538−-- | Same as 'dropWhile' but with a monadic predicate.
2541−{-# INLINE dropWhileM #-}
2542−dropWhileM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a
2543−dropWhileM p m = fromStreamD $ D.dropWhileM p $ toStreamD m
2545−-- | @dropByTime duration@ drops stream elements until specified @duration@ has
2546−-- passed. The duration begins when the stream is evaluated for the first
2547−-- time. The time duration is checked /after/ generating a stream element, the
2548−-- element is yielded if the duration has expired otherwise it is dropped.
2550−-- The time elapsed before starting to generate the first element is /at most/
2551−-- @duration@, however, because the duration expiry is checked after the
2552−-- element is generated, the lower bound is indeterminate and depends on the
2553−-- time taken in generating an element.
2555−-- All elements are yielded if the duration is zero.
2559−{-# INLINE dropByTime #-}
2560−dropByTime ::(MonadIO m, IsStream t, TimeUnit64 d) => d -> t m a -> t m a
2561−dropByTime d = fromStreamD . D.dropByTime d . toStreamD
2563−------------------------------------------------------------------------------
2564−-- Transformation by Mapping
2565−------------------------------------------------------------------------------
2569−-- mapM f = sequence . map f
2572−-- Apply a monadic function to each element of the stream and replace it with
2573−-- the output of the resulting action.
2576−-- > drain $ S.mapM putStr $ S.fromList ["a", "b", "c"]
2579−-- drain $ S.replicateM 10 (return 1)
2580−-- & (serially . S.mapM (\\x -> threadDelay 1000000 >> print x))
2582−-- drain $ S.replicateM 10 (return 1)
2583−-- & (asyncly . S.mapM (\\x -> threadDelay 1000000 >> print x))
2586−-- /Concurrent (do not use with 'parallely' on infinite streams)/
2589−{-# INLINE_EARLY mapM #-}
2590−mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
2593−{-# RULES "mapM serial" mapM = mapMSerial #-}
2594−{-# INLINE mapMSerial #-}
2595−mapMSerial :: Monad m => (a -> m b) -> SerialT m a -> SerialT m b
2596−mapMSerial = Serial.mapM
2600−-- sequence = mapM id
2603−-- Replace the elements of a stream of monadic actions with the outputs of
2607−-- > drain $ S.sequence $ S.fromList [putStr "a", putStr "b", putStrLn "c"]
2610−-- drain $ S.replicateM 10 (return $ threadDelay 1000000 >> print 1)
2611−-- & (serially . S.sequence)
2613−-- drain $ S.replicateM 10 (return $ threadDelay 1000000 >> print 1)
2614−-- & (asyncly . S.sequence)
2617−-- /Concurrent (do not use with 'parallely' on infinite streams)/
2620−{-# INLINE sequence #-}
2621−sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
2622−sequence m = fromStreamS $ S.sequence (toStreamS m)
2626−-- The stateful step function can be simplified to @(s -> a -> m b)@ to provide
2627−-- a read-only environment. However, that would just be 'mapM'.
2629−-- The initial action could be @m (s, Maybe b)@, and we can also add a final
2630−-- action @s -> m (Maybe b)@. This can be used to get pre/post scan like
2631−-- functionality and also to flush the state in the end like scanlMAfter'.
2632−-- We can also use it along with a fusible version of bracket to get
2633−-- scanlMAfter' like functionality. See issue #677.
2635−-- This can be further generalized to a type similar to Fold/Parser, giving it
2636−-- filtering and parsing capability as well (this is in fact equivalent to
2639−-- smapM :: (s -> a -> m (Step s b)) -> m s -> t m a -> t m b
2642−-- | A stateful 'mapM', equivalent to a left scan, more like mapAccumL.
2643−-- Hopefully, this is a better alternative to @scan@. Separation of state from
2644−-- the output makes it easier to think in terms of a shared state, and also
2645−-- makes it easier to keep the state fully strict and the output lazy.
2647−-- See also: 'scanlM''
2651−{-# INLINE smapM #-}
2652−smapM :: (IsStream t, Monad m) =>
2653− (s -> a -> m (s, b))
2657−smapM step initial stream =
2658− -- XXX implement this directly instead of using scanlM'
2659− -- Once we have postscanlM' with monadic initial we can use this code
2660− -- let r = postscanlM'
2661− -- (\(s, _) a -> step s a)
2662− -- (fmap (,undefined) initial)
2664− let r = postscanlM'
2665− (\(s, _) a -> step s a)
2666− (fmap (,undefined) initial)
2668− in Serial.map snd r
2670−------------------------------------------------------------------------------
2672−------------------------------------------------------------------------------
2674−-- | Map a 'Maybe' returning function to a stream, filter out the 'Nothing'
2675−-- elements, and return a stream of values extracted from 'Just'.
2680−-- mapMaybe f = S.map 'fromJust' . S.filter 'isJust' . S.map f
2684−{-# INLINE mapMaybe #-}
2685−mapMaybe :: (IsStream t, Monad m) => (a -> Maybe b) -> t m a -> t m b
2686−mapMaybe f m = fromStreamS $ S.mapMaybe f $ toStreamS m
2688−-- | Like 'mapMaybe' but maps a monadic function.
2693−-- mapMaybeM f = S.map 'fromJust' . S.filter 'isJust' . S.mapM f
2696−-- /Concurrent (do not use with 'parallely' on infinite streams)/
2699−{-# INLINE_EARLY mapMaybeM #-}
2700−mapMaybeM :: (IsStream t, MonadAsync m, Functor (t m))
2701− => (a -> m (Maybe b)) -> t m a -> t m b
2702−mapMaybeM f = fmap fromJust . filter isJust . K.mapM f
2704−{-# RULES "mapMaybeM serial" mapMaybeM = mapMaybeMSerial #-}
2705−{-# INLINE mapMaybeMSerial #-}
2706−mapMaybeMSerial :: Monad m => (a -> m (Maybe b)) -> SerialT m a -> SerialT m b
2707−mapMaybeMSerial f m = fromStreamD $ D.mapMaybeM f $ toStreamD m
2709−-- | In a stream of 'Maybe's, discard 'Nothing's and unwrap 'Just's.
2713−catMaybes :: (IsStream t, Monad m, Functor (t m)) => t m (Maybe a) -> t m a
2714−catMaybes = fmap fromJust . filter isJust
2716−------------------------------------------------------------------------------
2717−-- Transformation by Reordering
2718−------------------------------------------------------------------------------
2720−-- XXX Use a compact region list to temporarily store the list, in both reverse
2721−-- as well as in reverse'.
2723−-- /Note:/ 'reverse'' is much faster than this, use that when performance
2726−-- > reverse = S.foldlT (flip S.cons) S.nil
2728−-- | Returns the elements of the stream in reverse order. The stream must be
2729−-- finite. Note that this necessarily buffers the entire stream in memory.
2731−-- /Since 0.7.0 (Monad m constraint)/
2734−{-# INLINE reverse #-}
2735−reverse :: (IsStream t, Monad m) => t m a -> t m a
2736−reverse s = fromStreamS $ S.reverse $ toStreamS s
2738−-- | Like 'reverse' but several times faster, requires a 'Storable' instance.
2741−{-# INLINE reverse' #-}
2742−reverse' :: (IsStream t, MonadIO m, Storable a) => t m a -> t m a
2743−reverse' s = fromStreamD $ D.reverse' $ toStreamD s
2745−------------------------------------------------------------------------------
2746−-- Transformation by Inserting
2747−------------------------------------------------------------------------------
2749−-- intersperseM = intersperseBySpan 1
2751−-- | Insert an effect and its output before consuming an element of a stream
2752−-- except the first one.
2755−-- >>> S.toList $ S.trace putChar $ S.intersperseM (putChar '.' >> return ',') $ S.fromList "hello"
2756−-- > h.,e.,l.,l.,o"h,e,l,l,o"
2760−{-# INLINE intersperseM #-}
2761−intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
2762−intersperseM m = fromStreamS . S.intersperseM m . toStreamS
2764−-- | Insert a side effect before consuming an element of a stream except the
2768−-- >>> S.drain $ S.trace putChar $ S.intersperseM_ (putChar '.') $ S.fromList "hello"
2773−{-# INLINE intersperseM_ #-}
2774−intersperseM_ :: (IsStream t, Monad m) => m b -> t m a -> t m a
2775−intersperseM_ m = fromStreamD . D.intersperseM_ m . toStreamD
2777−-- | Insert a pure value between successive elements of a stream.
2780−-- > S.toList $ S.intersperse ',' $ S.fromList "hello"
2785−{-# INLINE intersperse #-}
2786−intersperse :: (IsStream t, MonadAsync m) => a -> t m a -> t m a
2787−intersperse a = fromStreamS . S.intersperse a . toStreamS
2789−-- | Insert an effect and its output after consuming an element of a stream.
2792−-- >>> S.toList $ S.trace putChar $ S.intersperseSuffix (putChar '.' >> return ',') $ S.fromList "hello"
2793−-- > h.,e.,l.,l.,o.,"h,e,l,l,o,"
2797−{-# INLINE intersperseSuffix #-}
2798−intersperseSuffix :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
2799−intersperseSuffix m = fromStreamD . D.intersperseSuffix m . toStreamD
2801−-- | Insert a side effect after consuming an element of a stream.
2804−-- > S.mapM_ putChar $ S.intersperseSuffix_ (threadDelay 1000000) $ S.fromList "hello"
2809−{-# INLINE intersperseSuffix_ #-}
2810−intersperseSuffix_ :: (IsStream t, Monad m) => m b -> t m a -> t m a
2811−intersperseSuffix_ m = fromStreamD . D.intersperseSuffix_ m . toStreamD
2813−-- | Insert a side effect before consuming an element of a stream.
2816−-- >>> S.toList $ S.trace putChar $ S.interspersePrefix_ (putChar '.' >> return ',') $ S.fromList "hello"
2817−-- > .h.e.l.l.o"hello"
2820−-- See also: 'trace_'
2826−{-# INLINE interspersePrefix_ #-}
2827−interspersePrefix_ :: (IsStream t, MonadAsync m) => m b -> t m a -> t m a
2828−interspersePrefix_ m = mapM (\x -> void m >> return x)
2830−-- Note: delay must be serial.
2832−-- | Introduce a delay of specified seconds before consuming an element of the
2833−-- stream except the first one.
2836−-- >>> S.mapM_ print $ S.timestamped $ S.delay 1 $ S.enumerateFromTo 1 3
2837−-- > (AbsTime (TimeSpec {sec = 2502706, nsec = 751137000}),1)
2838−-- > (AbsTime (TimeSpec {sec = 2502707, nsec = 743535000}),2)
2839−-- > (AbsTime (TimeSpec {sec = 2502708, nsec = 749758000}),3)
2844−{-# INLINE delay #-}
2845−delay :: (IsStream t, MonadIO m) => Double -> t m a -> t m a
2846−delay n = intersperseM_ $ liftIO $ threadDelay $ round $ n * 1000000
2848−-- Note: delay must be serial.
2850−-- | Introduce a delay of specified seconds after consuming an element of a
2854−-- >>> S.mapM_ print $ S.timestamped $ S.delayPost 1 $ S.enumerateFromTo 1 3
2855−-- > (AbsTime (TimeSpec {sec = 2502826, nsec = 119030000}),1)
2856−-- > (AbsTime (TimeSpec {sec = 2502827, nsec = 111393000}),2)
2857−-- > (AbsTime (TimeSpec {sec = 2502828, nsec = 112221000}),3)
2862−{-# INLINE delayPost #-}
2863−delayPost :: (IsStream t, MonadIO m) => Double -> t m a -> t m a
2864−delayPost n = intersperseSuffix_ $ liftIO $ threadDelay $ round $ n * 1000000
2866−-- Note: delay must be serial, that's why 'trace_' is used.
2868−-- | Introduce a delay of specified seconds before consuming an element of a
2872−-- >>> S.mapM_ print $ S.timestamped $ S.delayPre 1 $ S.enumerateFromTo 1 3
2873−-- > (AbsTime (TimeSpec {sec = 2502207, nsec = 533177000}),1)
2874−-- > (AbsTime (TimeSpec {sec = 2502208, nsec = 530859000}),2)
2875−-- > (AbsTime (TimeSpec {sec = 2502209, nsec = 531619000}),3)
2880−{-# INLINE delayPre #-}
2881−delayPre :: (IsStream t, MonadIO m) => Double -> t m a -> t m a
2882−delayPre n = trace_ $ liftIO $ threadDelay $ round $ n * 1000000
2884−-- | Like 'intersperseSuffix' but intersperses an effectful action into the
2885−-- input stream after every @n@ elements and after the last element.
2888−-- > S.toList $ S.intersperseSuffixBySpan 2 (return ',') $ S.fromList "hello"
2894−{-# INLINE intersperseSuffixBySpan #-}
2895−intersperseSuffixBySpan :: (IsStream t, MonadAsync m)
2896− => Int -> m a -> t m a -> t m a
2897−intersperseSuffixBySpan n eff =
2898− fromStreamD . D.intersperseSuffixBySpan n eff . toStreamD
2901−-- | Intersperse a monadic action into the input stream after every @n@
2905−-- > S.toList $ S.intersperseBySpan 2 (return ',') $ S.fromList "hello"
2910−{-# INLINE intersperseBySpan #-}
2911−intersperseBySpan :: IsStream t => Int -> m a -> t m a -> t m a
2912−intersperseBySpan _n _f _xs = undefined
2915−-- | Intersperse a monadic action into the input stream after every @n@
2919−-- > S.drain $ S.interjectSuffix 1 (putChar ',') $ S.mapM (\\x -> threadDelay 1000000 >> putChar x) $ S.fromList "hello"
2924−{-# INLINE interjectSuffix #-}
2926− :: (IsStream t, MonadAsync m)
2927− => Double -> m a -> t m a -> t m a
2928−interjectSuffix n f xs = xs `Par.parallelFst` repeatM timed
2929− where timed = liftIO (threadDelay (round $ n * 1000000)) >> f
2931−-- | @insertBy cmp elem stream@ inserts @elem@ before the first element in
2932−-- @stream@ that is less than @elem@ when compared using @cmp@.
2935−-- insertBy cmp x = 'mergeBy' cmp ('yield' x)
2939−-- > S.toList $ S.insertBy compare 2 $ S.fromList [1,3,5]
2944−{-# INLINE insertBy #-}
2946− (IsStream t, Monad m) => (a -> a -> Ordering) -> a -> t m a -> t m a
2947−insertBy cmp x m = fromStreamS $ S.insertBy cmp x (toStreamS m)
2949−------------------------------------------------------------------------------
2951−------------------------------------------------------------------------------
2953−-- | Deletes the first occurrence of the element in the stream that satisfies
2954−-- the given equality predicate.
2957−-- > S.toList $ S.deleteBy (==) 3 $ S.fromList [1,3,3,5]
2962−{-# INLINE deleteBy #-}
2963−deleteBy :: (IsStream t, Monad m) => (a -> a -> Bool) -> a -> t m a -> t m a
2964−deleteBy cmp x m = fromStreamS $ S.deleteBy cmp x (toStreamS m)
2966−------------------------------------------------------------------------------
2968−------------------------------------------------------------------------------
2971−-- > indexed = S.postscanl' (\(i, _) x -> (i + 1, x)) (-1,undefined)
2972−-- > indexed = S.zipWith (,) (S.enumerateFrom 0)
2974−-- Pair each element in a stream with its index, starting from index 0.
2977−-- > S.toList $ S.indexed $ S.fromList "hello"
2978−-- [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
2982−{-# INLINE indexed #-}
2983−indexed :: (IsStream t, Monad m) => t m a -> t m (Int, a)
2984−indexed = fromStreamD . D.indexed . toStreamD
2987−-- > indexedR n = S.postscanl' (\(i, _) x -> (i - 1, x)) (n + 1,undefined)
2988−-- > indexedR n = S.zipWith (,) (S.enumerateFromThen n (n - 1))
2990−-- Pair each element in a stream with its index, starting from the
2991−-- given index @n@ and counting down.
2994−-- > S.toList $ S.indexedR 10 $ S.fromList "hello"
2995−-- [(10,'h'),(9,'e'),(8,'l'),(7,'l'),(6,'o')]
2999−{-# INLINE indexedR #-}
3000−indexedR :: (IsStream t, Monad m) => Int -> t m a -> t m (Int, a)
3001−indexedR n = fromStreamD . D.indexedR n . toStreamD
3003−-- Note: The timestamp stream must be the second stream in the zip so that the
3004−-- timestamp is generated after generating the stream element and not before.
3005−-- If we do not do that then the following example will generate the same
3006−-- timestamp for first two elements:
3008−-- S.mapM_ print $ S.timestamped $ S.delay $ S.enumerateFromTo 1 3
3010−-- | Pair each element in a stream with an absolute timestamp, using a clock of
3011−-- specified granularity. The timestamp is generated just before the element
3015−-- >>> S.mapM_ print $ S.timestampWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
3020−{-# INLINE timestampWith #-}
3021−timestampWith :: (IsStream t, MonadAsync m, Functor (t m))
3022− => Double -> t m a -> t m (AbsTime, a)
3023−timestampWith g stream = Z.zipWith (flip (,)) stream (absTimesWith g)
3025−-- TBD: check performance vs a custom implementation without using zipWith.
3027−-- | Pair each element in a stream with an absolute timestamp, using a clock of
3028−-- 10 ms granularity. The timestamp is generated just before the element is
3032−-- >>> S.mapM_ print $ S.timestamped $ S.delay 1 $ S.enumerateFromTo 1 3
3033−-- (AbsTime (TimeSpec {sec = 2460689, nsec = 641121000}),1)
3034−-- (AbsTime (TimeSpec {sec = 2460690, nsec = 639334000}),2)
3035−-- (AbsTime (TimeSpec {sec = 2460691, nsec = 644479000}),3)
3040−{-# INLINE timestamped #-}
3041−timestamped :: (IsStream t, MonadAsync m, Functor (t m))
3042− => t m a -> t m (AbsTime, a)
3043−timestamped = timestampWith 0.01
3045−-- | Pair each element in a stream with relative times starting from 0, using a
3046−-- clock with the specified granularity. The time is measured just before the
3047−-- element is consumed.
3050−-- >>> S.mapM_ print $ S.timeIndexWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
3055−{-# INLINE timeIndexWith #-}
3056−timeIndexWith :: (IsStream t, MonadAsync m, Functor (t m))
3057− => Double -> t m a -> t m (RelTime64, a)
3058−timeIndexWith g stream = Z.zipWith (flip (,)) stream (relTimesWith g)
3060−-- | Pair each element in a stream with relative times starting from 0, using a
3061−-- 10 ms granularity clock. The time is measured just before the element is
3065−-- >>> S.mapM_ print $ S.timeIndexed $ S.delay 1 $ S.enumerateFromTo 1 3
3066−-- (RelTime64 (NanoSecond64 0),1)
3067−-- (RelTime64 (NanoSecond64 996239000),2)
3068−-- (RelTime64 (NanoSecond64 1996712000),3)
3073−{-# INLINE timeIndexed #-}
3074−timeIndexed :: (IsStream t, MonadAsync m, Functor (t m))
3075− => t m a -> t m (RelTime64, a)
3076−timeIndexed = timeIndexWith 0.01
3078−------------------------------------------------------------------------------
3080−------------------------------------------------------------------------------
3082−-- | Compare two streams for equality using an equality function.
3085−{-# INLINABLE eqBy #-}
3086−eqBy :: (IsStream t, Monad m) => (a -> b -> Bool) -> t m a -> t m b -> m Bool
3089−-- | Compare two streams lexicographically using a comparison function.
3092−{-# INLINABLE cmpBy #-}
3094− :: (IsStream t, Monad m)
3095− => (a -> b -> Ordering) -> t m a -> t m b -> m Ordering
3098−------------------------------------------------------------------------------
3100−------------------------------------------------------------------------------
3102−-- | Merge two streams using a comparison function. The head elements of both
3103−-- the streams are compared and the smaller of the two elements is emitted, if
3104−-- both elements are equal then the element from the first stream is used
3107−-- If the streams are sorted in ascending order, the resulting stream would
3108−-- also remain sorted in ascending order.
3111−-- > S.toList $ S.mergeBy compare (S.fromList [1,3,5]) (S.fromList [2,4,6,8])
3116−{-# INLINABLE mergeBy #-}
3118− (IsStream t, Monad m) => (a -> a -> Ordering) -> t m a -> t m a -> t m a
3119−mergeBy f m1 m2 = fromStreamS $ S.mergeBy f (toStreamS m1) (toStreamS m2)
3121−-- | Like 'mergeBy' but with a monadic comparison function.
3123−-- Merge two streams randomly:
3126−-- > randomly _ _ = randomIO >>= \x -> return $ if x then LT else GT
3127−-- > S.toList $ S.mergeByM randomly (S.fromList [1,1,1,1]) (S.fromList [2,2,2,2])
3128−-- [2,1,2,2,2,1,1,1]
3131−-- Merge two streams in a proportion of 2:1:
3134−-- proportionately m n = do
3135−-- ref <- newIORef $ cycle $ concat [replicate m LT, replicate n GT]
3136−-- return $ \\_ _ -> do
3137−-- r <- readIORef ref
3138−-- writeIORef ref $ tail r
3142−-- f <- proportionately 2 1
3143−-- xs <- S.toList $ S.mergeByM f (S.fromList [1,1,1,1,1,1]) (S.fromList [2,2,2])
3147−-- [1,1,2,1,1,2,1,1,2]
3151−{-# INLINABLE mergeByM #-}
3153− :: (IsStream t, Monad m)
3154− => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
3155−mergeByM f m1 m2 = fromStreamS $ S.mergeByM f (toStreamS m1) (toStreamS m2)
3158−-- | Like 'mergeByM' but stops merging as soon as any of the two streams stops.
3159−{-# INLINABLE mergeEndByAny #-}
3161− :: (IsStream t, Monad m)
3162− => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
3163−mergeEndByAny f m1 m2 = fromStreamD $
3164− D.mergeEndByAny f (toStreamD m1) (toStreamD m2)
3166−-- Like 'mergeByM' but stops merging as soon as the first stream stops.
3167−{-# INLINABLE mergeEndByFirst #-}
3169− :: (IsStream t, Monad m)
3170− => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
3171−mergeEndByFirst f m1 m2 = fromStreamS $
3172− D.mergeEndByFirst f (toStreamD m1) (toStreamD m2)
3175−-- Holding this back for now, we may want to use the name "merge" differently
3177−-- | Same as @'mergeBy' 'compare'@.
3180−-- > S.toList $ S.merge (S.fromList [1,3,5]) (S.fromList [2,4,6,8])
3185−{-# INLINABLE merge #-}
3187− (IsStream t, Monad m, Ord a) => t m a -> t m a -> t m a
3188−merge = mergeBy compare
3191−-- | Like 'mergeBy' but merges concurrently (i.e. both the elements being
3192−-- merged are generated concurrently).
3195−{-# INLINE mergeAsyncBy #-}
3196−mergeAsyncBy :: (IsStream t, MonadAsync m)
3197− => (a -> a -> Ordering) -> t m a -> t m a -> t m a
3198−mergeAsyncBy f = mergeAsyncByM (\a b -> return $ f a b)
3200−-- | Like 'mergeByM' but merges concurrently (i.e. both the elements being
3201−-- merged are generated concurrently).
3204−{-# INLINE mergeAsyncByM #-}
3205−mergeAsyncByM :: (IsStream t, MonadAsync m)
3206− => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
3207−mergeAsyncByM f m1 m2 = fromStreamD $
3208− D.mergeByM f (D.mkParallelD $ toStreamD m1) (D.mkParallelD $ toStreamD m2)
3210−------------------------------------------------------------------------------
3212−------------------------------------------------------------------------------
3214−-- | @concatMapWith merge map stream@ is a two dimensional looping combinator.
3215−-- The first argument specifies a merge or concat function that is used to
3216−-- merge the streams generated by applying the second argument i.e. the @map@
3217−-- function to each element of the input stream. The concat function could be
3218−-- 'serial', 'parallel', 'async', 'ahead' or any other zip or merge function
3219−-- and the second argument could be any stream generation function using a
3222−-- /Compare 'foldMapWith'/
3226−-- /Since: 0.8.0 (signature change)/
3227−{-# INLINE concatMapWith #-}
3230− => (t m b -> t m b -> t m b)
3234−concatMapWith = K.concatMapBy
3236−-- | Like 'concatMapWith' but carries a state which can be used to share
3237−-- information across multiple steps of concat.
3240−-- concatSmapMWith combine f initial = concatMapWith combine id . smapM f initial
3245−{-# INLINE concatSmapMWith #-}
3247− :: (IsStream t, Monad m)
3248− => (t m b -> t m b -> t m b)
3249− -> (s -> a -> m (s, t m b))
3253−concatSmapMWith combine f initial = concatMapWith combine id . smapM f initial
3255−-- | Map a stream producing function on each element of the stream and then
3256−-- flatten the results into a single stream.
3259−-- concatMap f = 'concat . map f'
3260−-- concatMap = 'concatMapWith' 'Serial.serial'
3261−-- concatMap f = 'concatMapM' (return . f)
3262−-- concatMap f = 'concatUnfold' (UF.lmap f UF.fromStream)
3266−{-# INLINE concatMap #-}
3267−concatMap ::(IsStream t, Monad m) => (a -> t m b) -> t m a -> t m b
3268−concatMap f m = fromStreamD $ D.concatMap (toStreamD . f) (toStreamD m)
3270−-- | Flatten a stream of streams to a single stream.
3273−-- concat = concatMap id
3277−{-# INLINE concat #-}
3278−concat :: (IsStream t, Monad m) => t m (t m a) -> t m a
3279−concat = concatMap id
3281−-- | Append the outputs of two streams, yielding all the elements from the
3282−-- first stream and then yielding all the elements from the second stream.
3284−-- IMPORTANT NOTE: This could be 100x faster than @serial/<>@ for appending a
3285−-- few (say 100) streams because it can fuse via stream fusion. However, it
3286−-- does not scale for a large number of streams (say 1000s) and becomes
3287−-- qudartically slow. Therefore use this for custom appending of a few streams
3288−-- but use 'concatMap' or 'concatMapWith serial' for appending @n@ streams or
3289−-- infinite containers of streams.
3292−{-# INLINE append #-}
3293−append ::(IsStream t, Monad m) => t m b -> t m b -> t m b
3294−append m1 m2 = fromStreamD $ D.append (toStreamD m1) (toStreamD m2)
3296−-- XXX Same as 'wSerial'. We should perhaps rename wSerial to interleave.
3297−-- XXX Document the interleaving behavior of side effects in all the
3298−-- interleaving combinators.
3299−-- XXX Write time-domain equivalents of these. In the time domain we can
3300−-- interleave two streams such that the value of second stream is always taken
3301−-- from its last value even if no new value is being yielded, like
3302−-- zipWithLatest. It would be something like interleaveWithLatest.
3304−-- | Interleaves the outputs of two streams, yielding elements from each stream
3305−-- alternately, starting from the first stream. If any of the streams finishes
3306−-- early the other stream continues alone until it too finishes.
3308−-- >>> :set -XOverloadedStrings
3309−-- >>> interleave "ab" ",,,," :: SerialT Identity Char
3310−-- fromList "a,b,,,"
3311−-- >>> interleave "abcd" ",," :: SerialT Identity Char
3312−-- fromList "a,b,cd"
3314−-- 'interleave' is dual to 'interleaveMin', it can be called @interleaveMax@.
3316−-- Do not use at scale in concatMapWith.
3319−{-# INLINE interleave #-}
3320−interleave ::(IsStream t, Monad m) => t m b -> t m b -> t m b
3321−interleave m1 m2 = fromStreamD $ D.interleave (toStreamD m1) (toStreamD m2)
3323−-- | Interleaves the outputs of two streams, yielding elements from each stream
3324−-- alternately, starting from the first stream. As soon as the first stream
3325−-- finishes, the output stops, discarding the remaining part of the second
3326−-- stream. In this case, the last element in the resulting stream would be from
3327−-- the second stream. If the second stream finishes early then the first stream
3328−-- still continues to yield elements until it finishes.
3330−-- >>> :set -XOverloadedStrings
3331−-- >>> interleaveSuffix "abc" ",,,," :: SerialT Identity Char
3332−-- fromList "a,b,c,"
3333−-- >>> interleaveSuffix "abc" "," :: SerialT Identity Char
3336−-- 'interleaveSuffix' is a dual of 'interleaveInfix'.
3338−-- Do not use at scale in concatMapWith.
3341−{-# INLINE interleaveSuffix #-}
3342−interleaveSuffix ::(IsStream t, Monad m) => t m b -> t m b -> t m b
3343−interleaveSuffix m1 m2 =
3344− fromStreamD $ D.interleaveSuffix (toStreamD m1) (toStreamD m2)
3346−-- | Interleaves the outputs of two streams, yielding elements from each stream
3347−-- alternately, starting from the first stream and ending at the first stream.
3348−-- If the second stream is longer than the first, elements from the second
3349−-- stream are infixed with elements from the first stream. If the first stream
3350−-- is longer then it continues yielding elements even after the second stream
3353−-- >>> :set -XOverloadedStrings
3354−-- >>> interleaveInfix "abc" ",,,," :: SerialT Identity Char
3356−-- >>> interleaveInfix "abc" "," :: SerialT Identity Char
3359−-- 'interleaveInfix' is a dual of 'interleaveSuffix'.
3361−-- Do not use at scale in concatMapWith.
3364−{-# INLINE interleaveInfix #-}
3365−interleaveInfix ::(IsStream t, Monad m) => t m b -> t m b -> t m b
3366−interleaveInfix m1 m2 =
3367− fromStreamD $ D.interleaveInfix (toStreamD m1) (toStreamD m2)
3369−-- | Interleaves the outputs of two streams, yielding elements from each stream
3370−-- alternately, starting from the first stream. The output stops as soon as any
3371−-- of the two streams finishes, discarding the remaining part of the other
3372−-- stream. The last element of the resulting stream would be from the longer
3375−-- >>> :set -XOverloadedStrings
3376−-- >>> interleaveMin "ab" ",,,," :: SerialT Identity Char
3378−-- >>> interleaveMin "abcd" ",," :: SerialT Identity Char
3381−-- 'interleaveMin' is dual to 'interleave'.
3383−-- Do not use at scale in concatMapWith.
3386−{-# INLINE interleaveMin #-}
3387−interleaveMin ::(IsStream t, Monad m) => t m b -> t m b -> t m b
3388−interleaveMin m1 m2 = fromStreamD $ D.interleaveMin (toStreamD m1) (toStreamD m2)
3390−-- | Schedule the execution of two streams in a fair round-robin manner,
3391−-- executing each stream once, alternately. Execution of a stream may not
3392−-- necessarily result in an output, a stream may chose to @Skip@ producing an
3393−-- element until later giving the other stream a chance to run. Therefore, this
3394−-- combinator fairly interleaves the execution of two streams rather than
3395−-- fairly interleaving the output of the two streams. This can be useful in
3396−-- co-operative multitasking without using explicit threads. This can be used
3397−-- as an alternative to `async`.
3399−-- Do not use at scale in concatMapWith.
3402−{-# INLINE roundrobin #-}
3403−roundrobin ::(IsStream t, Monad m) => t m b -> t m b -> t m b
3404−roundrobin m1 m2 = fromStreamD $ D.roundRobin (toStreamD m1) (toStreamD m2)
3406−-- | Map a stream producing monadic function on each element of the stream
3407−-- and then flatten the results into a single stream. Since the stream
3408−-- generation function is monadic, unlike 'concatMap', it can produce an
3409−-- effect at the beginning of each iteration of the inner loop.
3412−{-# INLINE concatMapM #-}
3413−concatMapM :: (IsStream t, Monad m) => (a -> m (t m b)) -> t m a -> t m b
3414−concatMapM f m = fromStreamD $ D.concatMapM (fmap toStreamD . f) (toStreamD m)
3416−-- | Given a stream value in the underlying monad, lift and join the underlying
3417−-- monad with the stream monad.
3420−-- concatM = concat . yieldM
3421−-- concatM = concat . lift -- requires @(MonadTrans t)@
3422−-- concatM = join . lift -- requires @(MonadTrans t@, @Monad (t m))@
3425−-- See also: 'concat', 'sequence'
3429−{-# INLINE concatM #-}
3430−concatM :: (IsStream t, Monad m) => m (t m a) -> t m a
3431−concatM generator = concatMapM (\() -> generator) (yield ())
3433−-- | Like 'concatMap' but uses an 'Unfold' for stream generation. Unlike
3434−-- 'concatMap' this can fuse the 'Unfold' code with the inner loop and
3435−-- therefore provide many times better performance.
3438−{-# INLINE concatUnfold #-}
3439−concatUnfold ::(IsStream t, Monad m) => Unfold m a b -> t m a -> t m b
3440−concatUnfold u m = fromStreamD $ D.concatMapU u (toStreamD m)
3442−-- | Like 'concatUnfold' but interleaves the streams in the same way as
3443−-- 'interleave' behaves instead of appending them.
3446−{-# INLINE concatUnfoldInterleave #-}
3447−concatUnfoldInterleave ::(IsStream t, Monad m)
3448− => Unfold m a b -> t m a -> t m b
3449−concatUnfoldInterleave u m =
3450− fromStreamD $ D.concatUnfoldInterleave u (toStreamD m)
3452−-- | Like 'concatUnfold' but executes the streams in the same way as
3456−{-# INLINE concatUnfoldRoundrobin #-}
3457−concatUnfoldRoundrobin ::(IsStream t, Monad m)
3458− => Unfold m a b -> t m a -> t m b
3459−concatUnfoldRoundrobin u m =
3460− fromStreamD $ D.concatUnfoldRoundrobin u (toStreamD m)
3462−-- XXX we can swap the order of arguments to gintercalate so that the
3463−-- definition of concatUnfold becomes simpler? The first stream should be
3464−-- infixed inside the second one. However, if we change the order in
3465−-- "interleave" as well similarly, then that will make it a bit unintuitive.
3467−-- > concatUnfold unf str =
3468−-- > gintercalate unf str (UF.nilM (\_ -> return ())) (repeat ())
3470−-- | 'interleaveInfix' followed by unfold and concat.
3473−{-# INLINE gintercalate #-}
3475− :: (IsStream t, Monad m)
3476− => Unfold m a c -> t m a -> Unfold m b c -> t m b -> t m c
3477−gintercalate unf1 str1 unf2 str2 =
3478− D.fromStreamD $ D.gintercalate
3479− unf1 (D.toStreamD str1)
3480− unf2 (D.toStreamD str2)
3482−-- XXX The order of arguments in "intercalate" is consistent with the list
3483−-- intercalate but inconsistent with gintercalate and other stream interleaving
3484−-- combinators. We can change the order of the arguments in other combinators
3485−-- but then 'interleave' combinator may become a bit unintuitive because we
3486−-- will be starting with the second stream.
3488−-- > intercalate seed unf str = gintercalate unf str unf (repeatM seed)
3489−-- > intercalate a unf str = concatUnfold unf $ intersperse a str
3491−-- | 'intersperse' followed by unfold and concat.
3493−-- > unwords = intercalate " " UF.fromList
3495−-- >>> intercalate " " UF.fromList ["abc", "def", "ghi"]
3499−{-# INLINE intercalate #-}
3500−intercalate :: (IsStream t, Monad m)
3501− => b -> Unfold m b c -> t m b -> t m c
3502−intercalate seed unf str = D.fromStreamD $
3503− D.concatMapU unf $ D.intersperse seed (toStreamD str)
3505−-- > interpose x unf str = gintercalate unf str UF.identity (repeat x)
3507−-- | Unfold the elements of a stream, intersperse the given element between the
3508−-- unfolded streams and then concat them into a single stream.
3510−-- > unwords = S.interpose ' '
3513−{-# INLINE interpose #-}
3514−interpose :: (IsStream t, Monad m)
3515− => c -> Unfold m b c -> t m b -> t m c
3516−interpose x unf str =
3517− D.fromStreamD $ D.interpose (return x) unf (D.toStreamD str)
3519−-- | 'interleaveSuffix' followed by unfold and concat.
3522−{-# INLINE gintercalateSuffix #-}
3524− :: (IsStream t, Monad m)
3525− => Unfold m a c -> t m a -> Unfold m b c -> t m b -> t m c
3526−gintercalateSuffix unf1 str1 unf2 str2 =
3527− D.fromStreamD $ D.gintercalateSuffix
3528− unf1 (D.toStreamD str1)
3529− unf2 (D.toStreamD str2)
3531−-- > intercalateSuffix seed unf str = gintercalateSuffix unf str unf (repeatM seed)
3532−-- > intercalateSuffix a unf str = concatUnfold unf $ intersperseSuffix a str
3534−-- | 'intersperseSuffix' followed by unfold and concat.
3536−-- > unlines = intercalateSuffix "\n" UF.fromList
3538−-- >>> intercalate "\n" UF.fromList ["abc", "def", "ghi"]
3539−-- > "abc\ndef\nghi\n"
3542−{-# INLINE intercalateSuffix #-}
3543−intercalateSuffix :: (IsStream t, Monad m)
3544− => b -> Unfold m b c -> t m b -> t m c
3545−intercalateSuffix seed unf str = fromStreamD $ D.concatMapU unf
3546− $ D.intersperseSuffix (return seed) (D.toStreamD str)
3548−-- interposeSuffix x unf str = gintercalateSuffix unf str UF.identity (repeat x)
3550−-- | Unfold the elements of a stream, append the given element after each
3551−-- unfolded stream and then concat them into a single stream.
3553−-- > unlines = S.interposeSuffix '\n'
3556−{-# INLINE interposeSuffix #-}
3557−interposeSuffix :: (IsStream t, Monad m)
3558− => c -> Unfold m b c -> t m b -> t m c
3559−interposeSuffix x unf str =
3560− D.fromStreamD $ D.interposeSuffix (return x) unf (D.toStreamD str)
3562−------------------------------------------------------------------------------
3564−------------------------------------------------------------------------------
3566−-- | Like 'iterateM' but iterates after mapping a stream generator on the
3569−-- Yield an input element in the output stream, map a stream generator on it
3570−-- and then do the same on the resulting stream. This can be used for a depth
3571−-- first traversal of a tree like structure.
3573−-- Note that 'iterateM' is a special case of 'iterateMapWith':
3576−-- iterateM f = iterateMapWith serial (yieldM . f) . yieldM
3579−-- It can be used to traverse a tree structure. For example, to list a
3583−-- Stream.iterateMapWith Stream.serial
3584−-- (either Dir.toEither (const nil))
3585−-- (yield (Left "tmp"))
3590−{-# INLINE iterateMapWith #-}
3593− => (t m a -> t m a -> t m a)
3597−iterateMapWith combine f = concatMapWith combine go
3599− go x = yield x `combine` concatMapWith combine go (f x)
3602−{-# INLINE iterateUnfold #-}
3603−iterateUnfold :: (IsStream t, MonadAsync m)
3604− => Unfold m a a -> t m a -> t m a
3605−iterateUnfold unf xs = undefined
3608−------------------------------------------------------------------------------
3609−-- Flattening Graphs
3610−------------------------------------------------------------------------------
3612−-- To traverse graphs we need a state to be carried around in the traversal.
3613−-- For example, we can use a hashmap to store the visited status of nodes.
3615−-- | Like 'iterateMap' but carries a state in the stream generation function.
3616−-- This can be used to traverse graph like structures, we can remember the
3617−-- visited nodes in the state to avoid cycles.
3619−-- Note that a combination of 'iterateMap' and 'usingState' can also be used to
3620−-- traverse graphs. However, this function provides a more localized state
3621−-- instead of using a global state.
3627−{-# INLINE iterateSmapMWith #-}
3629− :: (IsStream t, Monad m)
3630− => (t m a -> t m a -> t m a)
3631− -> (b -> a -> m (b, t m a))
3635−iterateSmapMWith combine f initial stream =
3636− concatMap (\b -> concatMapWith combine (go b) stream) (yieldM initial)
3640− go b a = yield a `combine` feedback b a
3644− (\(b1, s) -> concatMapWith combine (go b1) s)
3647−------------------------------------------------------------------------------
3649−------------------------------------------------------------------------------
3651−-- | Discard 'Right's and unwrap 'Left's in an 'Either' stream.
3655−lefts :: (IsStream t, Monad m, Functor (t m)) => t m (Either a b) -> t m a
3656−lefts = fmap (fromLeft undefined) . filter isLeft
3658−-- | Discard 'Left's and unwrap 'Right's in an 'Either' stream.
3662−rights :: (IsStream t, Monad m, Functor (t m)) => t m (Either a b) -> t m b
3663−rights = fmap (fromRight undefined) . filter isRight
3665−-- | In an 'Either' stream iterate on 'Left's. This is a special case of
3666−-- 'iterateMapWith':
3669−-- iterateMapLeftsWith combine f = iterateMapWith combine (either f (const nil))
3672−-- To traverse a directory tree:
3675−-- iterateMapLeftsWith serial Dir.toEither (yield (Left "tmp"))
3680−{-# INLINE iterateMapLeftsWith #-}
3683− => (t m (Either a b) -> t m (Either a b) -> t m (Either a b))
3684− -> (a -> t m (Either a b))
3685− -> t m (Either a b)
3686− -> t m (Either a b)
3687−iterateMapLeftsWith combine f = iterateMapWith combine (either f (const K.nil))
3689−------------------------------------------------------------------------------
3690−-- Folding/Parsing chunks in a stream
3691−------------------------------------------------------------------------------
3693−-- Splitting operations that take a predicate and a Fold can be
3694−-- expressed using parseMany. Operations like chunksOf, intervalsOf, split*,
3695−-- can be expressed using parseMany when used with an appropriate Parser.
3697−-- XXX We need takeGE/takeBetween to implement "some" using "many".
3699−-- | Apply a 'Fold' repeatedly on a stream and emit the parsed values in the
3702−-- This is the streaming dual of the 'Streamly.Internal.Data.Fold.many'
3703−-- parse combinator.
3705−-- >>> f = Fold.ltake 2 Fold.sum
3706−-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList [1..10]
3709−-- >>> f = Fold.sliceEndWith Fold.toList
3710−-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList "hello\nworld"
3711−-- > ["hello\n","world"]
3715−{-# INLINE foldMany #-}
3717− :: (IsStream t, Monad m)
3721−foldMany f m = D.fromStreamD $ D.foldMany f (D.toStreamD m)
3723−-- | Apply a stream of folds to an input stream and emit the results in the
3728−{-# INLINE foldSequence #-}
3730− :: -- (IsStream t, Monad m) =>
3734−foldSequence _f _m = undefined
3736−-- | Iterate a fold generator on a stream. The initial value @b@ is used to
3737−-- generate the first fold, the fold is applied on the stream and the result of
3738−-- the fold is used to generate the next fold and so on.
3740−-- >>> f x = Fold.ltake 2 (Fold.mconcatTo x)
3741−-- >>> s = Stream.map Sum $ Stream.fromList [1..10]
3742−-- >>> Stream.toList $ Stream.map getSum $ Stream.foldIterate f 0 s
3743−-- > [3,10,21,36,55,55]
3745−-- This is the streaming equivalent of monad like sequenced application of
3746−-- folds where next fold is dependent on the previous fold.
3750−{-# INLINE foldIterate #-}
3752− :: -- (IsStream t, Monad m) =>
3757−foldIterate _f _i _m = undefined
3758−-- D.fromStreamD $ D.foldIterate f i (D.toStreamD m)
3760−-- | Apply a 'Parser' repeatedly on a stream and emit the parsed values in the
3763−-- This is the streaming equivalent of the 'Streamly.Internal.Data.Parser.many'
3764−-- parse combinator.
3766−-- >>> S.toList $ S.parseMany (PR.take 2 $ PR.fromFold FL.sum) $ S.fromList [1..10]
3769−-- >>> S.toList $ S.parseMany (PR.line FL.toList) $ S.fromList "hello\nworld"
3770−-- > ["hello\n","world"]
3774−{-# INLINE parseMany #-}
3776− :: (IsStream t, MonadThrow m)
3781− D.fromStreamD $ D.parseMany (PRK.fromParserK p) (D.toStreamD m)
3783−{-# INLINE parseManyD #-}
3785− :: (IsStream t, MonadThrow m)
3786− => PRD.Parser m a b
3790− D.fromStreamD $ D.parseMany p (D.toStreamD m)
3792−-- | Apply a stream of parsers to an input stream and emit the results in the
3797−{-# INLINE parseSequence #-}
3799− :: -- (IsStream t, Monad m) =>
3803−parseSequence _f _m = undefined
3805−-- | @parseManyTill collect test stream@ tries the parser @test@ on the input,
3806−-- if @test@ fails it backtracks and tries @collect@, after @collect@ succeeds
3807−-- @test@ is tried again and so on. The parser stops when @test@ succeeds. The
3808−-- output of @test@ is discarded and the output of @collect@ is emitted in the
3809−-- output stream. The parser fails if @collect@ fails.
3813−{-# INLINE parseManyTill #-}
3815− -- (IsStream t, MonadThrow m) =>
3820−parseManyTill = undefined
3822−-- | Iterate a parser generating function on a stream. The initial value @b@ is
3823−-- used to generate the first parser, the parser is applied on the stream and
3824−-- the result is used to generate the next parser and so on.
3826−-- >>> S.toList $ S.map getSum $ S.parseIterate (\b -> PR.take 2 (FL.mconcatTo b)) 0 $ S.map Sum $ S.fromList [1..10]
3827−-- > [3,10,21,36,55,55]
3829−-- This is the streaming equivalent of monad like sequenced application of
3830−-- parsers where next parser is dependent on the previous parser.
3834−{-# INLINE parseIterate #-}
3836− :: (IsStream t, MonadThrow m)
3837− => (b -> Parser m a b)
3841−parseIterate f i m = D.fromStreamD $
3842− D.parseIterate (PRK.fromParserK . f) i (D.toStreamD m)
3844−------------------------------------------------------------------------------
3845−-- Grouping/Splitting
3846−------------------------------------------------------------------------------
3848−------------------------------------------------------------------------------
3849−-- Grouping without looking at elements
3850−------------------------------------------------------------------------------
3852−------------------------------------------------------------------------------
3854−------------------------------------------------------------------------------
3857−------------------------------------------------------------------------------
3859−------------------------------------------------------------------------------
3861−------------------------------------------------------------------------------
3862−-- Generalized grouping
3863−------------------------------------------------------------------------------
3865−-- This combinator is the most general grouping combinator and can be used to
3866−-- implement all other grouping combinators.
3868−-- XXX check if this can implement the splitOn combinator i.e. we can slide in
3869−-- new elements, slide out old elements and incrementally compute the hash.
3870−-- Also, can we implement the windowed classification combinators using this?
3872−-- In fact this is a parse. Instead of using a special return value in the fold
3873−-- we are using a mapping function.
3875−-- Note that 'scanl'' (usually followed by a map to extract the desired value
3876−-- from the accumulator) can be used to realize many implementations e.g. a
3877−-- sliding window implementation. A scan followed by a mapMaybe is also a good
3878−-- pattern to express many problems where we want to emit a filtered output and
3879−-- not emit an output on every input.
3881−-- Passing on of the initial accumulator value to the next fold is equivalent
3882−-- to returning the leftover concept.
3885−-- | @groupScan splitter fold stream@ folds the input stream using @fold@.
3886−-- @splitter@ is applied on the accumulator of the fold every time an item is
3887−-- consumed by the fold. The fold continues until @splitter@ returns a 'Just'
3888−-- value. A 'Just' result from the @splitter@ specifies a result to be emitted
3889−-- in the output stream and the initial value of the accumulator for the next
3890−-- group's fold. This allows us to control whether to start fresh for the next
3891−-- fold or to continue from the previous fold's output.
3893−{-# INLINE groupScan #-}
3895− :: (IsStream t, Monad m)
3896− => (x -> m (Maybe (b, x))) -> Fold m a x -> t m a -> t m b
3897−groupScan split fold m = undefined
3900−-- | Group the input stream into groups of @n@ elements each and then fold each
3901−-- group using the provided fold function.
3903−-- >> S.toList $ S.chunksOf 2 FL.sum (S.enumerateFromTo 1 10)
3906−-- This can be considered as an n-fold version of 'ltake' where we apply
3907−-- 'ltake' repeatedly on the leftover stream until the stream exhausts.
3910−{-# INLINE chunksOf #-}
3912− :: (IsStream t, Monad m)
3913− => Int -> Fold m a b -> t m a -> t m b
3914−chunksOf n f = foldMany (FL.ltake n f)
3919−{-# INLINE chunksOf2 #-}
3921− :: (IsStream t, Monad m)
3922− => Int -> m c -> Fold2 m c a b -> t m a -> t m b
3923−chunksOf2 n action f m = D.fromStreamD $ D.groupsOf2 n action f (D.toStreamD m)
3925−-- | @arraysOf n stream@ groups the elements in the input stream into arrays of
3926−-- @n@ elements each.
3928−-- Same as the following but may be more efficient:
3930−-- > arraysOf n = S.chunksOf n (A.writeN n)
3933−{-# INLINE arraysOf #-}
3934−arraysOf :: (IsStream t, MonadIO m, Storable a)
3935− => Int -> t m a -> t m (Array a)
3936−arraysOf n = chunksOf n (writeNUnsafe n)
3938−-- XXX we can implement this by repeatedly applying the 'lrunFor' fold.
3939−-- XXX add this example after fixing the serial stream rate control
3940−-- >>> S.toList $ S.take 5 $ intervalsOf 1 FL.sum $ constRate 2 $ S.enumerateFrom 1
3943−-- | Group the input stream into windows of @n@ second each and then fold each
3944−-- group using the provided fold function.
3947−{-# INLINE intervalsOf #-}
3949− :: (IsStream t, MonadAsync m)
3950− => Double -> Fold m a b -> t m a -> t m b
3951−intervalsOf n f xs =
3952− splitWithSuffix isNothing (FL.lcatMaybes f)
3953− (interjectSuffix n (return Nothing) (Serial.map Just xs))
3955------------------------------------------------------------------------------
674------------------------------------------------------------------------------
3956−-- N-ary APIs
675+-- Specialized folds
3957------------------------------------------------------------------------------
676------------------------------------------------------------------------------
3959−-- | @groupsBy cmp f $ S.fromList [a,b,c,...]@ assigns the element @a@ to the
678+-- |
3960−-- first group, if @b \`cmp` a@ is 'True' then @b@ is also assigned to the same
679+-- > drainN n = drain . take n
3961−-- group. If @c \`cmp` a@ is 'True' then @c@ is also assigned to the same
680+-- > drainN n = fold (Fold.ltake n Fold.drain)
3962−-- group and so on. When the comparison fails a new group is started. Each
3963−-- group is folded using the fold @f@ and the result of the fold is emitted in
3964−-- the output stream.
3966−-- >>> S.toList $ S.groupsBy (>) FL.toList $ S.fromList [1,3,7,0,2,5]
682+-- Run maximum up to @n@ iterations of a stream.
3967−-- > [[1,3,7],[0,2,5]]
3969-- @since 0.7.0
684-- @since 0.7.0
3970−{-# INLINE groupsBy #-}
685+{-# INLINE drainN #-}
3971−groupsBy
686+drainN :: Monad m => Int -> SerialT m a -> m ()
3972− :: (IsStream t, Monad m)
687+drainN n = drain . take n
3973− => (a -> a -> Bool)
688+
3974− -> Fold m a b
689+-- |
3975− -> t m a
690+-- > runN n = runStream . take n
3977−groupsBy cmp f m = D.fromStreamD $ D.groupsBy cmp f (D.toStreamD m)
3979−-- | Unlike @groupsBy@ this function performs a rolling comparison of two
3980−-- successive elements in the input stream. @groupsByRolling cmp f $ S.fromList
3981−-- [a,b,c,...]@ assigns the element @a@ to the first group, if @a \`cmp` b@ is
3982−-- 'True' then @b@ is also assigned to the same group. If @b \`cmp` c@ is
3983−-- 'True' then @c@ is also assigned to the same group and so on. When the
3984−-- comparison fails a new group is started. Each group is folded using the fold
3987−-- >>> S.toList $ S.groupsByRolling (\a b -> a + 1 == b) FL.toList $ S.fromList [1,2,3,7,8,9]
692+-- Run maximum up to @n@ iterations of a stream.
3988−-- > [[1,2,3],[7,8,9]]
3990−-- @since 0.7.0
694+-- @since 0.6.0
3991−{-# INLINE groupsByRolling #-}
695+{-# DEPRECATED runN "Please use \"drainN\" instead" #-}
3992−groupsByRolling
696+{-# INLINE runN #-}
3993− :: (IsStream t, Monad m)
697+runN :: Monad m => Int -> SerialT m a -> m ()
3994− => (a -> a -> Bool)
698+runN = drainN
3998−groupsByRolling cmp f m = D.fromStreamD $ D.groupsRollingBy cmp f (D.toStreamD m)
4001−-- > groups = groupsBy (==)
701+-- > drainWhile p = drain . takeWhile p
4002−-- > groups = groupsByRolling (==)
702+-- > drainWhile p = fold (Fold.sliceSepBy (not . p) Fold.drain)
4004−-- Groups contiguous spans of equal elements together in individual groups.
4006−-- >>> S.toList $ S.groups FL.toList $ S.fromList [1,1,2,2]
704+-- Run a stream as long as the predicate holds true.
4009-- @since 0.7.0
706-- @since 0.7.0
4010−{-# INLINE groups #-}
707+{-# INLINE drainWhile #-}
4011−groups :: (IsStream t, Monad m, Eq a) => Fold m a b -> t m a -> t m b
708+drainWhile :: Monad m => (a -> Bool) -> SerialT m a -> m ()
4012−groups = groupsBy (==)
709+drainWhile p = drain . takeWhile p
712+-- > runWhile p = runStream . takeWhile p
714+-- Run a stream as long as the predicate holds true.
717+{-# DEPRECATED runWhile "Please use \"drainWhile\" instead" #-}
718+{-# INLINE runWhile #-}
719+runWhile :: Monad m => (a -> Bool) -> SerialT m a -> m ()
720+runWhile = drainWhile
4014------------------------------------------------------------------------------
722------------------------------------------------------------------------------
4015−-- N-ary split on a predicate
723+-- Transformation by Inserting
4016------------------------------------------------------------------------------
724------------------------------------------------------------------------------
4018−-- TODO: Use a Splitter configuration similar to the "split" package to make it
726+-- | Intersperse a monadic action into the input stream after every @n@
4019−-- possible to express all splitting combinations. In general, we can have
727+-- seconds.
4020−-- infix/suffix/prefix/condensing of separators, dropping both leading/trailing
4021−-- separators. We can have a single split operation taking the splitter config
4024−-- | Split on an infixed separator element, dropping the separator. Splits the
4025−-- stream on separator elements determined by the supplied predicate, separator
4026−-- is considered as infixed between two segments, if one side of the separator
4027−-- is missing then it is parsed as an empty stream. The supplied 'Fold' is
4028−-- applied on the split segments. With '-' representing non-separator elements
4029−-- and '.' as separator, 'splitOn' splits as follows:
4032−-- "--.--" => "--" "--"
730+-- > S.drain $ S.interjectSuffix 1 (putChar ',') $ S.mapM (\\x -> threadDelay 1000000 >> putChar x) $ S.fromList "hello"
4033−-- "--." => "--" ""
731+-- "h,e,l,l,o"
4037−-- @splitOn (== x)@ is an inverse of @intercalate (S.yield x)@
734+-- /Internal/
4038−--
735+{-# INLINE interjectSuffix #-}
4039−-- Let's use the following definition for illustration:
736+interjectSuffix
4040−--
737+ :: (IsStream t, MonadAsync m)
4041−-- > splitOn' p xs = S.toList $ S.splitOn p (FL.toList) (S.fromList xs)
738+ => Double -> m a -> t m a -> t m a
4042−--
739+interjectSuffix n f xs = xs `Par.parallelFst` repeatM timed
4043−-- >>> splitOn' (== '.') ""
740+ where timed = liftIO (threadDelay (round $ n * 1000000)) >> f
4045−--
742+-------------------------------------------------------------------------------
4046−-- >>> splitOn' (== '.') "."
743+-- Indexing
4047−-- ["",""]
744+-------------------------------------------------------------------------------
746+-- Note: The timestamp stream must be the second stream in the zip so that the
747+-- timestamp is generated after generating the stream element and not before.
748+-- If we do not do that then the following example will generate the same
749+-- timestamp for first two elements:
4049−-- >>> splitOn' (== '.') ".a"
751+-- S.mapM_ print $ S.timestamped $ S.delay $ S.enumerateFromTo 1 3
4052−-- >>> splitOn' (== '.') "a."
753+-- | Pair each element in a stream with an absolute timestamp, using a clock of
4053−-- > ["a",""]
754+-- specified granularity. The timestamp is generated just before the element
4055−-- >>> splitOn' (== '.') "a.b"
757+-- @
4056−-- > ["a","b"]
758+-- >>> S.mapM_ print $ S.timestampWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
4058−-- >>> splitOn' (== '.') "a..b"
761+-- /Internal/
4061−-- @since 0.7.0
763+{-# INLINE timestampWith #-}
764+timestampWith :: (IsStream t, MonadAsync m, Functor (t m))
765+ => Double -> t m a -> t m (AbsTime, a)
766+timestampWith g stream = Z.zipWith (flip (,)) stream (absTimesWith g)
4063−-- This can be considered as an n-fold version of 'breakOn' where we apply
768+-- TBD: check performance vs a custom implementation without using zipWith.
4064−-- 'breakOn' successively on the input stream, dropping the first element
4065−-- of the second segment after each break.
4067−{-# INLINE splitOn #-}
772+{-# INLINE timestamped #-}
4068−splitOn
773+timestamped :: (IsStream t, MonadAsync m, Functor (t m))
4069− :: (IsStream t, Monad m)
774+ => t m a -> t m (AbsTime, a)
4070− => (a -> Bool) -> Fold m a b -> t m a -> t m b
775+timestamped = timestampWith 0.01
4071−splitOn predicate f = foldMany (FL.sliceSepBy predicate f)
4073−-- | Like 'splitOn' but the separator is considered as suffixed to the segments
777+-- | Pair each element in a stream with relative times starting from 0, using a
4074−-- in the stream. A missing suffix at the end is allowed. A separator at the
778+-- clock with the specified granularity. The time is measured just before the
4075−-- beginning is parsed as empty segment. With '-' representing elements and
779+-- element is consumed.
4076−-- '.' as separator, 'splitOnSuffix' splits as follows:
4079−-- "--.--." => "--" "--"
782+-- >>> S.mapM_ print $ S.timeIndexWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
4080−-- "--.--" => "--" "--"
4081−-- ".--." => "" "--"
4084−-- > splitOnSuffix' p xs = S.toList $ S.splitSuffixBy p (FL.toList) (S.fromList xs)
785+-- /Internal/
4086−-- >>> splitOnSuffix' (== '.') ""
4089−-- >>> splitOnSuffix' (== '.') "."
4092−-- >>> splitOnSuffix' (== '.') "a"
4095−-- >>> splitOnSuffix' (== '.') ".a"
4098−-- >>> splitOnSuffix' (== '.') "a."
4101−-- >>> splitOnSuffix' (== '.') "a.b"
4104−-- >>> splitOnSuffix' (== '.') "a.b."
4107−-- >>> splitOnSuffix' (== '.') "a..b.."
4108−-- > ["a","","b",""]
4110−-- > lines = splitOnSuffix (== '\n')
4112−-- @since 0.7.0
787+{-# INLINE timeIndexWith #-}
788+timeIndexWith :: (IsStream t, MonadAsync m, Functor (t m))
789+ => Double -> t m a -> t m (RelTime64, a)
790+timeIndexWith g stream = Z.zipWith (flip (,)) stream (relTimesWith g)
4114−-- This can be considered as an n-fold version of 'breakPost' where we apply
792+-- | Pair each element in a stream with relative times starting from 0, using a
4115−-- 'breakPost' successively on the input stream, dropping the first element
793+-- 10 ms granularity clock. The time is measured just before the element is
4116−-- of the second segment after each break.
794+-- consumed.
4118−{-# INLINE splitOnSuffix #-}
4120− :: (IsStream t, Monad m)
4121− => (a -> Bool) -> Fold m a b -> t m a -> t m b
4122−splitOnSuffix predicate f m =
4123− D.fromStreamD $ D.foldMany1 (FL.sliceSepBy predicate f) (D.toStreamD m)
4125−-- | Like 'splitOn' after stripping leading, trailing, and repeated separators.
4126−-- Therefore, @".a..b."@ with '.' as the separator would be parsed as
4127−-- @["a","b"]@. In other words, its like parsing words from whitespace
4130−-- > wordsBy' p xs = S.toList $ S.wordsBy p (FL.toList) (S.fromList xs)
4132−-- >>> wordsBy' (== ',') ""
4135−-- >>> wordsBy' (== ',') ","
4138−-- >>> wordsBy' (== ',') ",a,,b,"
796+-- @
4139−-- > ["a","b"]
797+-- >>> S.mapM_ print $ S.timeIndexed $ S.delay 1 $ S.enumerateFromTo 1 3
798+-- (RelTime64 (NanoSecond64 0),1)
799+-- (RelTime64 (NanoSecond64 996239000),2)
800+-- (RelTime64 (NanoSecond64 1996712000),3)
4141−-- > words = wordsBy isSpace
803+-- /Internal/
4143−-- @since 0.7.0
805+{-# INLINE timeIndexed #-}
806+timeIndexed :: (IsStream t, MonadAsync m, Functor (t m))
807+ => t m a -> t m (RelTime64, a)
808+timeIndexed = timeIndexWith 0.01
4145−-- It is equivalent to splitting in any of the infix/prefix/suffix styles
810+------------------------------------------------------------------------------
4146−-- followed by removal of empty segments.
811+-- Searching
4147−{-# INLINE wordsBy #-}
812+------------------------------------------------------------------------------
4149− :: (IsStream t, Monad m)
4150− => (a -> Bool) -> Fold m a b -> t m a -> t m b
4151−wordsBy predicate f m =
4152− D.fromStreamD $ D.wordsBy predicate f (D.toStreamD m)
4154−-- | Like 'splitOnSuffix' but keeps the suffix attached to the resulting
814+-- | Returns the first index that satisfies the given predicate.
4157−-- > splitWithSuffix' p xs = S.toList $ S.splitWithSuffix p (FL.toList) (S.fromList xs)
4159−-- >>> splitWithSuffix' (== '.') ""
4162−-- >>> splitWithSuffix' (== '.') "."
4165−-- >>> splitWithSuffix' (== '.') "a"
4168−-- >>> splitWithSuffix' (== '.') ".a"
4171−-- >>> splitWithSuffix' (== '.') "a."
4174−-- >>> splitWithSuffix' (== '.') "a.b"
4177−-- >>> splitWithSuffix' (== '.') "a.b."
4180−-- >>> splitWithSuffix' (== '.') "a..b.."
816+-- > findIndex = fold Fold.findIndex
4181−-- > ["a.",".","b.","."]
4183−-- @since 0.7.0
818+-- @since 0.5.0
819+{-# INLINE findIndex #-}
820+findIndex :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe Int)
821+findIndex p = head . findIndices p
4185−-- This can be considered as an n-fold version of 'breakPost' where we apply
823+-- | Returns the first index where a given value is found in the stream.
4186−-- 'breakPost' successively on the input stream.
4188−{-# INLINE splitWithSuffix #-}
825+-- > elemIndex a = findIndex (== a)
4189−splitWithSuffix
826+--
4190− :: (IsStream t, Monad m)
827+-- @since 0.5.0
4191− => (a -> Bool) -> Fold m a b -> t m a -> t m b
828+{-# INLINE elemIndex #-}
4192−splitWithSuffix predicate f m =
829+elemIndex :: (Monad m, Eq a) => a -> SerialT m a -> m (Maybe Int)
4193− D.fromStreamD $ D.foldMany1 (FL.sliceEndWith predicate f) (D.toStreamD m)
830+elemIndex a = findIndex (== a)
4195------------------------------------------------------------------------------
832------------------------------------------------------------------------------
4196−-- Split on a delimiter sequence
833+-- Substreams
4197------------------------------------------------------------------------------
834------------------------------------------------------------------------------
4199−-- Int list examples for splitOn:
836+-- | Returns 'True' if the first stream is a suffix of the second. A stream is
4200−--
837+-- considered a suffix of itself.
4201−-- >>> splitList [] [1,2,3,3,4]
4202−-- > [[1],[2],[3],[3],[4]]
4204−-- >>> splitList [5] [1,2,3,3,4]
4207−-- >>> splitList [1] [1,2,3,3,4]
4210−-- >>> splitList [4] [1,2,3,3,4]
839+-- @
4211−-- > [[1,2,3,3],[]]
840+-- > S.isSuffixOf (S.fromList "hello") (S.fromList "hello" :: SerialT IO Char)
4213−-- >>> splitList [2] [1,2,3,3,4]
844+-- Space: @O(n)@, buffers entire input stream and the suffix.
4216−-- >>> splitList [3] [1,2,3,3,4]
846+-- /Internal/
4219−-- >>> splitList [3,3] [1,2,3,3,4]
848+-- /Suboptimal/ - Help wanted.
4222−-- >>> splitList [1,2,3,3,4] [1,2,3,3,4]
850+{-# INLINE isSuffixOf #-}
4223−-- > [[],[]]
851+isSuffixOf :: (Monad m, Eq a) => SerialT m a -> SerialT m a -> m Bool
852+isSuffixOf suffix stream = reverse suffix `isPrefixOf` reverse stream
4225−-- | Like 'splitOn' but the separator is a sequence of elements instead of a
854+-- | Returns 'True' if the first stream is an infix of the second. A stream is
4226−-- single element.
855+-- considered an infix of itself.
4228−-- For illustration, let's define a function that operates on pure lists:
4231−-- splitOnSeq' pat xs = S.toList $ S.splitOnSeq (A.fromList pat) (FL.toList) (S.fromList xs)
858+-- > S.isInfixOf (S.fromList "hello") (S.fromList "hello" :: SerialT IO Char)
4234−-- >>> splitOnSeq' "" "hello"
862+-- Space: @O(n)@ worst case where @n@ is the length of the infix.
4235−-- > ["h","e","l","l","o"]
4237−-- >>> splitOnSeq' "hello" ""
4240−-- >>> splitOnSeq' "hello" "hello"
4243−-- >>> splitOnSeq' "x" "hello"
4246−-- >>> splitOnSeq' "h" "hello"
4249−-- >>> splitOnSeq' "o" "hello"
4252−-- >>> splitOnSeq' "e" "hello"
4255−-- >>> splitOnSeq' "l" "hello"
4258−-- >>> splitOnSeq' "ll" "hello"
4261−-- 'splitOnSeq' is an inverse of 'intercalate'. The following law always holds:
4263−-- > intercalate . splitOn == id
4265−-- The following law holds when the separator is non-empty and contains none of
4266−-- the elements present in the input lists:
4268−-- > splitOn . intercalate == id
4270-- /Internal/
864-- /Internal/
4272−-- XXX We can use a polymorphic vector implemented by Array# to represent the
4273−-- sequence, that way we can avoid the Storable constraint. If we still need
4274−-- Storable Array for performance, we can use a separate splitOnArray API for
4275−-- that. We can also have an API where the sequence itself is a lazy stream, so
4276−-- that we can search files in files for example.
4277−{-# INLINE splitOnSeq #-}
4279− :: (IsStream t, MonadIO m, Storable a, Enum a, Eq a)
4280− => Array a -> Fold m a b -> t m a -> t m b
4281−splitOnSeq patt f m = D.fromStreamD $ D.splitOnSeq patt f (D.toStreamD m)
4284−-- This can be implemented easily using Rabin Karp
4285−-- | Split on any one of the given patterns.
4286−{-# INLINE splitOnAny #-}
4288− :: (IsStream t, Monad m, Storable a, Integral a)
4289− => [Array a] -> Fold m a b -> t m a -> t m b
4290−splitOnAny subseq f m = undefined -- D.fromStreamD $ D.splitOnAny f subseq (D.toStreamD m)
4293−-- | Like 'splitSuffixBy' but the separator is a sequence of elements, instead
4294−-- of a predicate for a single element.
4296−-- > splitOnSuffixSeq_ pat xs = S.toList $ S.splitOnSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
4298−-- >>> splitOnSuffixSeq_ "." ""
4301−-- >>> splitOnSuffixSeq_ "." "."
866+-- /Requires 'Storable' constraint/ - Help wanted.
4304−-- >>> splitOnSuffixSeq_ "." "a"
4307−-- >>> splitOnSuffixSeq_ "." ".a"
4310−-- >>> splitOnSuffixSeq_ "." "a."
4313−-- >>> splitOnSuffixSeq_ "." "a.b"
4316−-- >>> splitOnSuffixSeq_ "." "a.b."
4319−-- >>> splitOnSuffixSeq_ "." "a..b.."
4320−-- > ["a","","b",""]
4322−-- > lines = splitOnSuffixSeq "\n"
4324−-- 'splitOnSuffixSeq' is an inverse of 'intercalateSuffix'. The following law
868+{-# INLINE isInfixOf #-}
4325−-- always holds:
869+isInfixOf :: (MonadIO m, Eq a, Enum a, Storable a)
870+ => SerialT m a -> SerialT m a -> m Bool
871+isInfixOf infx stream = do
872+ arr <- fold A.write infx
873+ -- XXX can use breakOnSeq instead (when available)
874+ r <- null $ drop 1 $ splitOnSeq arr FL.drain stream
877+-- Note: If we want to return a Maybe value to know whether the
878+-- suffix/infix was present or not along with the stripped stream then
879+-- we need to buffer the whole input stream.
4327−-- > intercalateSuffix . splitOnSuffixSeq == id
881+-- | Drops the given suffix from a stream. Returns 'Nothing' if the stream does
882+-- not end with the given suffix. Returns @Just nil@ when the suffix is the
883+-- same as the stream.
4329−-- The following law holds when the separator is non-empty and contains none of
885+-- It may be more efficient to convert the stream to an Array and use
4330−-- the elements present in the input lists:
886+-- stripSuffix on that especially if the elements have a Storable or Prim
4332−-- > splitSuffixOn . intercalateSuffix == id
889+-- Space: @O(n)@, buffers the entire input stream as well as the suffix
4334-- /Internal/
891-- /Internal/
4335−{-# INLINE splitOnSuffixSeq #-}
892+{-# INLINE stripSuffix #-}
4336−splitOnSuffixSeq
893+stripSuffix
4337− :: (IsStream t, MonadIO m, Storable a, Enum a, Eq a)
894+ :: (Monad m, Eq a)
4338− => Array a -> Fold m a b -> t m a -> t m b
895+ => SerialT m a -> SerialT m a -> m (Maybe (SerialT m a))
4339−splitOnSuffixSeq patt f m =
896+stripSuffix m1 m2 = fmap reverse <$> stripPrefix (reverse m1) (reverse m2)
4340− D.fromStreamD $ D.splitOnSuffixSeq False patt f (D.toStreamD m)
4342−{-
898+------------------------------------------------------------------------------
4343−-- | Like 'splitOn' but drops any empty splits.
899+-- Split on a delimiter sequence
4344−--
900+------------------------------------------------------------------------------
4345−{-# INLINE wordsOn #-}
4347− :: (IsStream t, Monad m, Storable a, Eq a)
4348− => Array a -> Fold m a b -> t m a -> t m b
4349−wordsOn subseq f m = undefined -- D.fromStreamD $ D.wordsOn f subseq (D.toStreamD m)
4352-- XXX use a non-monadic intersperse to remove the MonadAsync constraint.
902-- XXX use a non-monadic intersperse to remove the MonadAsync constraint.
@@ -4390,276 +940,160 @@ splitBySeq
4390splitBySeq patt f m =
940splitBySeq patt f m =
4391 intersperseM (fold f (A.toStream patt)) $ splitOnSeq patt f m
941 intersperseM (fold f (A.toStream patt)) $ splitOnSeq patt f m
4393−-- | Like 'splitOnSuffixSeq' but keeps the suffix intact in the splits.
943+------------------------------------------------------------------------------
4394−--
944+-- Flattening Trees
4395−-- > splitWithSuffixSeq'_ pat xs = S.toList $ S.splitWithSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
945+------------------------------------------------------------------------------
4397−-- >>> splitWithSuffixSeq' "." ""
947+-- | Like 'iterateM' but iterates after mapping a stream generator on the
4398−-- [""]
948+-- output.
4400−-- >>> splitWithSuffixSeq' "." "."
4403−-- >>> splitWithSuffixSeq' "." "a"
4406−-- >>> splitWithSuffixSeq' "." ".a"
950+-- Yield an input element in the output stream, map a stream generator on it
4407−-- > [".","a"]
951+-- and then do the same on the resulting stream. This can be used for a depth
952+-- first traversal of a tree like structure.
4409−-- >>> splitWithSuffixSeq' "." "a."
954+-- Note that 'iterateM' is a special case of 'iterateMapWith':
4412−-- >>> splitWithSuffixSeq' "." "a.b"
956+-- @
4413−-- > ["a.","b"]
957+-- iterateM f = iterateMapWith serial (yieldM . f) . yieldM
4415−-- >>> splitWithSuffixSeq' "." "a.b."
960+-- It can be used to traverse a tree structure. For example, to list a
4416−-- > ["a.","b."]
961+-- directory tree:
4418−-- >>> splitWithSuffixSeq' "." "a..b.."
963+-- @
4419−-- > ["a.",".","b.","."]
964+-- Stream.iterateMapWith Stream.serial
965+-- (either Dir.toEither (const nil))
966+-- (yield (Left "tmp"))
4421-- /Internal/
969-- /Internal/
4422−{-# INLINE splitWithSuffixSeq #-}
970+--
4423−splitWithSuffixSeq
971+{-# INLINE iterateMapWith #-}
4424− :: (IsStream t, MonadIO m, Storable a, Enum a, Eq a)
973+ :: IsStream t
4425− => Array a -> Fold m a b -> t m a -> t m b
974+ => (t m a -> t m a -> t m a)
4426−splitWithSuffixSeq patt f m =
975+ -> (a -> t m a)
4427− D.fromStreamD $ D.splitOnSuffixSeq True patt f (D.toStreamD m)
976+ -> t m a
978+iterateMapWith combine f = concatMapWith combine go
980+ go x = yield x `combine` concatMapWith combine go (f x)
4430−-- This can be implemented easily using Rabin Karp
983+{-# INLINE iterateUnfold #-}
4431−-- | Split post any one of the given patterns.
984+iterateUnfold :: (IsStream t, MonadAsync m)
4432−{-# INLINE splitOnSuffixSeqAny #-}
4434− :: (IsStream t, Monad m, Storable a, Integral a)
4435− => [Array a] -> Fold m a b -> t m a -> t m b
985+ => Unfold m a a -> t m a -> t m a
4436−splitOnSuffixSeqAny subseq f m = undefined
986+iterateUnfold unf xs = undefined
4437− -- D.fromStreamD $ D.splitPostAny f subseq (D.toStreamD m)
4440------------------------------------------------------------------------------
989------------------------------------------------------------------------------
4441−-- Nested Split
990+-- Flattening Graphs
4442------------------------------------------------------------------------------
991------------------------------------------------------------------------------
4444−-- | @splitInnerBy splitter joiner stream@ splits the inner containers @f a@ of
993+-- To traverse graphs we need a state to be carried around in the traversal.
4445−-- an input stream @t m (f a)@ using the @splitter@ function. Container
994+-- For example, we can use a hashmap to store the visited status of nodes.
4446−-- elements @f a@ are collected until a split occurs, then all the elements
995+
4447−-- before the split are joined using the @joiner@ function.
996+-- | Like 'iterateMap' but carries a state in the stream generation function.
997+-- This can be used to traverse graph like structures, we can remember the
998+-- visited nodes in the state to avoid cycles.
4449−-- For example, if we have a stream of @Array Word8@, we may want to split the
1000+-- Note that a combination of 'iterateMap' and 'usingState' can also be used to
4450−-- stream into arrays representing lines separated by '\n' byte such that the
1001+-- traverse graphs. However, this function provides a more localized state
4451−-- resulting stream after a split would be one array for each line.
1002+-- instead of using a global state.
4453−-- CAUTION! This is not a true streaming function as the container size after
1004+-- See also: 'mfix'
4454−-- the split and merge may not be bounded.
4456-- /Internal/
1006-- /Internal/
4457−{-# INLINE splitInnerBy #-}
4459− :: (IsStream t, Monad m)
4460− => (f a -> m (f a, Maybe (f a))) -- splitter
4461− -> (f a -> f a -> m (f a)) -- joiner
4464−splitInnerBy splitter joiner xs =
4465− D.fromStreamD $ D.splitInnerBy splitter joiner $ D.toStreamD xs
4467−-- | Like 'splitInnerBy' but splits assuming the separator joins the segment in
4470−-- /Internal/
1008+{-# INLINE iterateSmapMWith #-}
4471−{-# INLINE splitInnerBySuffix #-}
1009+iterateSmapMWith
4473− :: (IsStream t, Monad m, Eq (f a), Monoid (f a))
4474− => (f a -> m (f a, Maybe (f a))) -- splitter
4475− -> (f a -> f a -> m (f a)) -- joiner
4478−splitInnerBySuffix splitter joiner xs =
4479− D.fromStreamD $ D.splitInnerBySuffix splitter joiner $ D.toStreamD xs
4481−------------------------------------------------------------------------------
4482−-- Reorder in sequence
4483−------------------------------------------------------------------------------
4486−-- Buffer until the next element in sequence arrives. The function argument
4487−-- determines the difference in sequence numbers. This could be useful in
4488−-- implementing sequenced streams, for example, TCP reassembly.
4489−{-# INLINE reassembleBy #-}
4491 :: (IsStream t, Monad m)
1010 :: (IsStream t, Monad m)
4492− => Fold m a b
1011+ => (t m a -> t m a -> t m a)
4493− -> (a -> a -> Int)
1012+ -> (b -> a -> m (b, t m a))
4494 -> t m a
1014 -> t m a
4495− -> t m b
1015+ -> t m a
4496−reassembleBy = undefined
1016+iterateSmapMWith combine f initial stream =
4497−-}
1017+ concatMap (\b -> concatMapWith combine (go b) stream) (yieldM initial)
1021+ go b a = yield a `combine` feedback b a
1025+ (\(b1, s) -> concatMapWith combine (go b1) s)
4499------------------------------------------------------------------------------
1028------------------------------------------------------------------------------
4500−-- Distributing
1029+-- Flattening Lists
4501------------------------------------------------------------------------------
1030------------------------------------------------------------------------------
4503−-- | Tap the data flowing through a stream into a 'Fold'. For example, you may
1032+-- | Given a stream value in the underlying monad, lift and join the underlying
4504−-- add a tap to log the contents flowing through the stream. The fold is used
1033+-- monad with the stream monad.
4505−-- only for effects, its result is discarded.
4510−-- -----stream m a ---------------stream m a-----
4515−-- > S.drain $ S.tap (FL.drainBy print) (S.enumerateFromTo 1 2)
4520−-- Compare with 'trace'.
4524−tap :: (IsStream t, Monad m) => FL.Fold m a b -> t m a -> t m a
4525−tap f xs = D.fromStreamD $ D.tap f (D.toStreamD xs)
4527−-- | @tapOffsetEvery offset n@ taps every @n@th element in the stream
4528−-- starting at @offset@. @offset@ can be between @0@ and @n - 1@. Offset 0
4529−-- means start at the first element in the stream. If the offset is outside
4530−-- this range then @offset `mod` n@ is used as offset.
4533−-- >>> S.drain $ S.tapOffsetEvery 0 2 (FL.mapM print FL.toList) $ S.enumerateFromTo 0 10
1036+-- concatM = concat . yieldM
4534−-- > [0,2,4,6,8,10]
1037+-- concatM = concat . lift -- requires @(MonadTrans t)@
1038+-- concatM = join . lift -- requires @(MonadTrans t@, @Monad (t m))@
4537−-- /Internal/
1041+-- See also: 'concat', 'sequence'
4539−{-# INLINE tapOffsetEvery #-}
4540−tapOffsetEvery :: (IsStream t, Monad m)
4541− => Int -> Int -> FL.Fold m a b -> t m a -> t m a
4542−tapOffsetEvery offset n f xs =
4543− D.fromStreamD $ D.tapOffsetEvery offset n f (D.toStreamD xs)
4545−-- | Redirect a copy of the stream to a supplied fold and run it concurrently
4546−-- in an independent thread. The fold may buffer some elements. The buffer size
4547−-- is determined by the prevailing 'maxBuffer' setting.
4549−-- @
1043+-- /Internal/
4550−-- Stream m a -> m b
4552−-- -----stream m a ---------------stream m a-----
4554−-- @
1045+{-# INLINE concatM #-}
1046+concatM :: (IsStream t, Monad m) => m (t m a) -> t m a
1047+concatM generator = concatMapM (\() -> generator) (yield ())
1049+------------------------------------------------------------------------------
1051+------------------------------------------------------------------------------
1053+-- | In an 'Either' stream iterate on 'Left's. This is a special case of
1054+-- 'iterateMapWith':
4557−-- > S.drain $ S.tapAsync (S.mapM_ print) (S.enumerateFromTo 1 2)
1057+-- iterateMapLeftsWith combine f = iterateMapWith combine (either f (const nil))
4562−-- Exceptions from the concurrently running fold are propagated to the current
1060+-- To traverse a directory tree:
4563−-- computation. Note that, because of buffering in the fold, exceptions may be
4564−-- delayed and may not correspond to the current element being processed in the
4565−-- parent stream, but we guarantee that before the parent stream stops the tap
4566−-- finishes and all exceptions from it are drained.
4569−-- Compare with 'tap'.
4572−{-# INLINE tapAsync #-}
4573−tapAsync :: (IsStream t, MonadAsync m) => FL.Fold m a b -> t m a -> t m a
4574−tapAsync f xs = D.fromStreamD $ D.tapAsync f (D.toStreamD xs)
4576−-- | @pollCounts predicate transform fold stream@ counts those elements in the
4577−-- stream that pass the @predicate@. The resulting count stream is sent to
4578−-- another thread which transforms it using @transform@ and then folds it using
4579−-- @fold@. The thread is automatically cleaned up if the stream stops or
4580−-- aborts due to exception.
4582−-- For example, to print the count of elements processed every second:
4585−-- > S.drain $ S.pollCounts (const True) (S.rollingMap (-) . S.delayPost 1) (FL.drainBy print)
1063+-- iterateMapLeftsWith serial Dir.toEither (yield (Left "tmp"))
4586−-- $ S.enumerateFrom 0
4589−-- Note: This may not work correctly on 32-bit machines.
4591-- /Internal/
1066-- /Internal/
4593−{-# INLINE pollCounts #-}
1068+{-# INLINE iterateMapLeftsWith #-}
4594−pollCounts ::
1069+iterateMapLeftsWith
4595− (IsStream t, MonadAsync m)
1070+ :: IsStream t
4596− => (a -> Bool)
1071+ => (t m (Either a b) -> t m (Either a b) -> t m (Either a b))
4597− -> (t m Int -> t m Int)
1072+ -> (a -> t m (Either a b))
4598− -> Fold m Int b
1073+ -> t m (Either a b)
4599− -> t m a
1074+ -> t m (Either a b)
4600− -> t m a
1075+iterateMapLeftsWith combine f = iterateMapWith combine (either f (const K.nil))
4601−pollCounts predicate transf f xs =
4603− $ D.pollCounts predicate (D.toStreamD . transf . D.fromStreamD) f
4606−-- | Calls the supplied function with the number of elements consumed
4607−-- every @n@ seconds. The given function is run in a separate thread
4608−-- until the end of the stream. In case there is an exception in the
4609−-- stream the thread is killed during the next major GC.
4611−-- Note: The action is not guaranteed to run if the main thread exits.
4614−-- > delay n = threadDelay (round $ n * 1000000) >> return n
4615−-- > S.drain $ S.tapRate 2 (\\n -> print $ show n ++ " elements processed") (delay 1 S.|: delay 0.5 S.|: delay 0.5 S.|: S.nil)
4616−-- 2 elements processed
4617−-- 1 elements processed
4620−-- Note: This may not work correctly on 32-bit machines.
4623−{-# INLINE tapRate #-}
4625− (IsStream t, MonadAsync m, MonadCatch m)
4630−tapRate n f xs = D.fromStreamD $ D.tapRate n f $ D.toStreamD xs
4632−-- | Apply a monadic function to each element flowing through the stream and
1077+-------------------------------------------------------------------------------
4633−-- discard the results.
1078+-- Breaking
4634−--
1079+-------------------------------------------------------------------------------
4636−-- > S.drain $ S.trace print (S.enumerateFromTo 1 2)
4641−-- Compare with 'tap'.
4644−{-# INLINE trace #-}
4645−trace :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m a
4646−trace f = mapM (\x -> void (f x) >> return x)
4648−-- | Perform a side effect before yielding each element of the stream and
1081+-- XXX we can implement this by repeatedly applying the 'lrunFor' fold.
4649−-- discard the results.
1082+-- XXX add this example after fixing the serial stream rate control
4650−--
1083+-- >>> S.toList $ S.take 5 $ intervalsOf 1 FL.sum $ constRate 2 $ S.enumerateFrom 1
4651−-- @
1084+-- > [3,7,11,15,19]
4652−-- > S.drain $ S.trace_ (print "got here") (S.enumerateFromTo 1 2)
4657−-- See also: 'trace', 'interspersePrefix_'
1086+-- | Group the input stream into windows of @n@ second each and then fold each
1087+-- group using the provided fold function.
4659−-- /Internal/
1089+-- @since 0.7.0
4660−{-# INLINE trace_ #-}
1090+{-# INLINE intervalsOf #-}
4661−trace_ :: (IsStream t, Monad m) => m b -> t m a -> t m a
1092+ :: (IsStream t, MonadAsync m)
4662−trace_ eff = Serial.mapM (\x -> eff >> return x)
1093+ => Double -> Fold m a b -> t m a -> t m b
1094+intervalsOf n f xs =
1095+ splitWithSuffix isNothing (FL.lcatMaybes f)
1096+ (interjectSuffix n (return Nothing) (Serial.map Just xs))
4664------------------------------------------------------------------------------
1098------------------------------------------------------------------------------
4665-- Windowed classification
1099-- Windowed classification
@@ -5134,297 +1568,3 @@ classifySessionsOf ::
5134 -> t m (k, b)
1568 -> t m (k, b)
5135classifySessionsOf interval =
1569classifySessionsOf interval =
5136 classifySessionsBy 1 interval False
1570 classifySessionsBy 1 interval False
5138−------------------------------------------------------------------------------
5140−------------------------------------------------------------------------------
5142−-- | Run the action @m b@ before the stream yields its first element.
5144−-- > before action xs = 'nilM' action <> xs
5147−{-# INLINE before #-}
5148−before :: (IsStream t, Monad m) => m b -> t m a -> t m a
5149−before action xs = D.fromStreamD $ D.before action $ D.toStreamD xs
5151−-- | Like 'after', with following differences:
5153−-- * action @m b@ won't run if the stream is garbage collected
5154−-- after partial evaluation.
5155−-- * Monad @m@ does not require any other constraints.
5156−-- * has slightly better performance than 'after'.
5158−-- Same as the following, but with stream fusion:
5160−-- > after_ action xs = xs <> 'nilM' action
5164−{-# INLINE after_ #-}
5165−after_ :: (IsStream t, Monad m) => m b -> t m a -> t m a
5166−after_ action xs = D.fromStreamD $ D.after_ action $ D.toStreamD xs
5168−-- | Run the action @m b@ whenever the stream @t m a@ stops normally, or if it
5169−-- is garbage collected after a partial lazy evaluation.
5171−-- The semantics of the action @m b@ are similar to the semantics of cleanup
5172−-- action in 'bracket'.
5174−-- /See also 'after_'/
5178−{-# INLINE after #-}
5179−after :: (IsStream t, MonadIO m, MonadBaseControl IO m)
5180− => m b -> t m a -> t m a
5181−after action xs = D.fromStreamD $ D.after action $ D.toStreamD xs
5183−-- | Run the action @m b@ if the stream aborts due to an exception. The
5184−-- exception is not caught, simply rethrown.
5186−-- /Inhibits stream fusion/
5189−{-# INLINE onException #-}
5190−onException :: (IsStream t, MonadCatch m) => m b -> t m a -> t m a
5191−onException action xs = D.fromStreamD $ D.onException action $ D.toStreamD xs
5193−-- | Like 'finally' with following differences:
5195−-- * action @m b@ won't run if the stream is garbage collected
5196−-- after partial evaluation.
5197−-- * does not require a 'MonadAsync' constraint.
5198−-- * has slightly better performance than 'finally'.
5200−-- /Inhibits stream fusion/
5204−{-# INLINE finally_ #-}
5205−finally_ :: (IsStream t, MonadCatch m) => m b -> t m a -> t m a
5206−finally_ action xs = D.fromStreamD $ D.finally_ action $ D.toStreamD xs
5208−-- | Run the action @m b@ whenever the stream @t m a@ stops normally, aborts
5209−-- due to an exception or if it is garbage collected after a partial lazy
5212−-- The semantics of running the action @m b@ are similar to the cleanup action
5213−-- semantics described in 'bracket'.
5216−-- finally release = bracket (return ()) (const release)
5219−-- /See also 'finally_'/
5221−-- /Inhibits stream fusion/
5225−{-# INLINE finally #-}
5226−finally :: (IsStream t, MonadAsync m, MonadCatch m) => m b -> t m a -> t m a
5227−finally action xs = D.fromStreamD $ D.finally action $ D.toStreamD xs
5229−-- | Like 'bracket' but with following differences:
5231−-- * alloc action @m b@ runs with async exceptions enabled
5232−-- * cleanup action @b -> m c@ won't run if the stream is garbage collected
5233−-- after partial evaluation.
5234−-- * does not require a 'MonadAsync' constraint.
5235−-- * has slightly better performance than 'bracket'.
5237−-- /Inhibits stream fusion/
5241−{-# INLINE bracket_ #-}
5242−bracket_ :: (IsStream t, MonadCatch m)
5243− => m b -> (b -> m c) -> (b -> t m a) -> t m a
5244−bracket_ bef aft bet = D.fromStreamD $
5245− D.bracket_ bef aft (toStreamD . bet)
5247−-- | Run the alloc action @m b@ with async exceptions disabled but keeping
5248−-- blocking operations interruptible (see 'Control.Exception.mask'). Use the
5249−-- output @b@ as input to @b -> t m a@ to generate an output stream.
5251−-- @b@ is usually a resource under the state of monad @m@, e.g. a file
5252−-- handle, that requires a cleanup after use. The cleanup action @b -> m c@,
5253−-- runs whenever the stream ends normally, due to a sync or async exception or
5254−-- if it gets garbage collected after a partial lazy evaluation.
5256−-- 'bracket' only guarantees that the cleanup action runs, and it runs with
5257−-- async exceptions enabled. The action must ensure that it can successfully
5258−-- cleanup the resource in the face of sync or async exceptions.
5260−-- When the stream ends normally or on a sync exception, cleanup action runs
5261−-- immediately in the current thread context, whereas in other cases it runs in
5262−-- the GC context, therefore, cleanup may be delayed until the GC gets to run.
5264−-- /See also: 'bracket_'/
5266−-- /Inhibits stream fusion/
5270−{-# INLINE bracket #-}
5271−bracket :: (IsStream t, MonadAsync m, MonadCatch m)
5272− => m b -> (b -> m c) -> (b -> t m a) -> t m a
5273−bracket bef aft bet = D.fromStreamD $
5274− D.bracket bef aft (toStreamD . bet)
5276−-- | Like 'handle' but the exception handler is also provided with the stream
5277−-- that generated the exception as input. The exception handler can thus
5278−-- re-evaluate the stream to retry the action that failed. The exception
5279−-- handler can again call 'ghandle' on it to retry the action multiple times.
5281−-- This is highly experimental. In a stream of actions we can map the stream
5282−-- with a retry combinator to retry each action on failure.
5284−-- /Inhibits stream fusion/
5288−{-# INLINE ghandle #-}
5289−ghandle :: (IsStream t, MonadCatch m, Exception e)
5290− => (e -> t m a -> t m a) -> t m a -> t m a
5293− . D.ghandle (\e xs -> D.toStreamD $ handler e (D.fromStreamD xs))
5296−-- | When evaluating a stream if an exception occurs, stream evaluation aborts
5297−-- and the specified exception handler is run with the exception as argument.
5299−-- /Inhibits stream fusion/
5302−{-# INLINE handle #-}
5303−handle :: (IsStream t, MonadCatch m, Exception e)
5304− => (e -> t m a) -> t m a -> t m a
5306− D.fromStreamD $ D.handle (D.toStreamD . handler) $ D.toStreamD xs
5308−-- Keep concating either streams as long as rights are generated, stop as soon
5309−-- as a left is generated and concat the left stream.
5311−-- See also: 'handle'
5317− :: -- (IsStream t, MonadAsync m) =>
5318− (forall x. t m x -> t m x -> t m x)
5319− -> (a -> t m (Either (t m b) b))
5322−concatMapEitherWith = undefined
5325−------------------------------------------------------------------------------
5326−-- Generalize the underlying monad
5327−------------------------------------------------------------------------------
5329−-- | Transform the inner monad of a stream using a natural transformation.
5333−{-# INLINE hoist #-}
5334−hoist :: (Monad m, Monad n)
5335− => (forall x. m x -> n x) -> SerialT m a -> SerialT n a
5336−hoist f xs = fromStreamS $ S.hoist f (toStreamS xs)
5338−-- | Generalize the inner monad of the stream from 'Identity' to any monad.
5342−{-# INLINE generally #-}
5343−generally :: (IsStream t, Monad m) => t Identity a -> t m a
5344−generally xs = fromStreamS $ S.hoist (return . runIdentity) (toStreamS xs)
5346−------------------------------------------------------------------------------
5347−-- Add and remove a monad transformer
5348−------------------------------------------------------------------------------
5350−-- | Lift the inner monad @m@ of a stream @t m a@ to @tr m@ using the monad
5351−-- transformer @tr@.
5355−{-# INLINE liftInner #-}
5356−liftInner :: (Monad m, IsStream t, MonadTrans tr, Monad (tr m))
5357− => t m a -> t (tr m) a
5358−liftInner xs = fromStreamD $ D.liftInner (toStreamD xs)
5360−------------------------------------------------------------------------------
5361−-- Sharing read only state in a stream
5362−------------------------------------------------------------------------------
5364−-- | Evaluate the inner monad of a stream as 'ReaderT'.
5368−{-# INLINE runReaderT #-}
5369−runReaderT :: (IsStream t, Monad m) => m s -> t (ReaderT s m) a -> t m a
5370−runReaderT s xs = fromStreamD $ D.runReaderT s (toStreamD xs)
5372−-- | Run a stream transformation using a given environment.
5374−-- See also: 'Serial.map'
5378−{-# INLINE usingReaderT #-}
5380− :: (Monad m, IsStream t)
5382− -> (t (ReaderT r m) a -> t (ReaderT r m) a)
5385−usingReaderT r f xs = runReaderT r $ f $ liftInner xs
5387−------------------------------------------------------------------------------
5388−-- Sharing read write state in a stream
5389−------------------------------------------------------------------------------
5391−-- | Evaluate the inner monad of a stream as 'StateT'.
5393−-- This is supported only for 'SerialT' as concurrent state updation may not be
5398−{-# INLINE evalStateT #-}
5399−evalStateT :: Monad m => m s -> SerialT (StateT s m) a -> SerialT m a
5400−evalStateT s xs = fromStreamD $ D.evalStateT s (toStreamD xs)
5402−-- | Run a stateful (StateT) stream transformation using a given state.
5404−-- This is supported only for 'SerialT' as concurrent state updation may not be
5407−-- See also: 'scanl''
5411−{-# INLINE usingStateT #-}
5415− -> (SerialT (StateT s m) a -> SerialT (StateT s m) a)
5418−usingStateT s f xs = evalStateT s $ f $ liftInner xs
5420−-- | Evaluate the inner monad of a stream as 'StateT' and emit the resulting
5421−-- state and value pair after each step.
5423−-- This is supported only for 'SerialT' as concurrent state updation may not be
5428−{-# INLINE runStateT #-}
5429−runStateT :: Monad m => m s -> SerialT (StateT s m) a -> SerialT m (s, a)
5430−runStateT s xs = fromStreamD $ D.runStateT s (toStreamD xs)