@@ -28,6 +28,10 @@
2828-- provided for convenience and for consistency with other pure APIs in the
2929-- @base@ package.
3030--
31+-- In many cases, short definitions of the combinators are provided in the
32+-- documentation for illustration. The actual implementation may differ for
33+-- performance reasons.
34+--
3135-- Functions having a 'MonadAsync' constraint work concurrently when used with
3236-- appropriate stream type combinator. Please be careful to not use 'parallely'
3337-- with infinite streams.
@@ -41,74 +45,128 @@
4145module Streamly.Prelude
4246 (
4347 -- * Construction
44− -- | All other stream construction and generation combinators described
45− -- later, and even more custom combinators can be expressed in terms of
46− -- these primitives. However, the special versions provided in this module
47− -- can be more efficient in some situations.
48−
49− -- ** From Elements
48+ -- ** Primitives
5049 -- | Primitives to construct a stream from pure values or monadic actions.
50+ -- All other stream construction and generation combinators described later
51+ -- can be expressed in terms of these primitives. However, the special
52+ -- versions provided in this module can be much more efficient in most
53+ -- cases. Users can create custom combinators using these primitives.
54+
5155 K.nil
5256 , K.cons
5357 , (K..:)
5458
5559 , consM
5660 , (|:)
61+
62+ -- ** From Values
63+ -- | Generate a monadic stream from a seed value or values.
5764 , yield
5865 , yieldM
66+ , K.repeat
67+ , repeatM
68+ , replicate
69+ , replicateM
5970
60− -- ** From Streams
61− -- | You can construct streams by appending or merging existing streams.
62− -- When constructing streams from streams, '<>' and 'mempty' are the
63− -- intuitive equivalents of 'K.cons' and 'K.nil', respectively. These
64− -- primitives can be very useful when constructing your own custom stream
65− -- combinators. Also see the variants of '<>' defined in the "Streamly"
66− -- module. Note that appending streams is inexpensive, it is much more
67− -- efficient than appending lists.
68−
69− -- * Generation
70− -- ** Unfold and Iterate
71− -- | Note that the generative steps of unfold and iterate are inherently
72− -- serial as the next step depends on the result of the previous step.
73− -- However, consumption of the result from the previous step can happen in
74− -- parallel with the generation by the next step.
71+ -- ** Enumeration
72+ -- | The haskell 'Enum' typeclass provides enumerations for member types.
73+ -- However, the typeclass is tied to lists, it is impossible to use it to
74+ -- write enumeration functions producing something other than a list in a
75+ -- generic way.
76+ -- We can use the 'Enum' facilities to enumerate the type producing a list
77+ -- and then convert it to a stream:
78+ --
79+ -- @
80+ -- 'fromList' $ 'Prelude.enumFromThen' from then
81+ -- @
82+ --
83+ -- However, this is not particularly efficient. Note that using
84+ -- enumeration functions e.g. 'Prelude.enumFromThen' is slightly faster
85+ -- than the idioms like @[from, then..]@.
86+ --
87+ -- For the cases where speed matters, we have provided specific 'Enum' like
88+ -- implementations for enumeration.
89+ --
90+ , intFrom
91+ , intFromTo
92+ , intFromThen
93+ , intFromThenTo
94+ , intFromStep
95+
96+ , fracFrom
97+ , fracFromTo
98+ , fracFromThen
99+ , fracFromThenTo
100+ , numFromStep
101+
102+ -- ** From Generators
103+ -- | Generate a monadic stream from a seed value and a generator function.
75104 , unfoldr
76105 , unfoldrM
77106 , iterate
78107 , iterateM
108+ , fromIndices
109+ , fromIndicesM
79110
80− -- ** Replicate and Repeat
81− -- | Generate a monadic stream from a seed value or function. Note that
82− -- these functions can generate a stream fully concurrently as, unlike
83− -- unfolds, there is no dependency between steps, therefore, an unbounded
84− -- number of steps can run concurrently. All of these can be expressed in
85− -- terms of 'K.cons' and 'K.nil' primitives.
86− , replicateM
87− , replicate
88− , K.repeat
89− , repeatM
90−
91− -- ** Generate From
111+ -- ** From Containers
92112 -- | Convert an input structure, container or source into a stream. All of
93113 -- these can be expressed in terms of primitives.
94− , generate
95− , generateM
96114 , P.fromList
97115 , fromListM
98116 , K.fromFoldable
99117 , fromFoldableM
100− , fromHandle
101118
102− -- * Deconstruction
103− , uncons
119+ -- ** From External Containers
120+ , fromHandle
104121
105122 -- * Elimination
106123
124+ -- ** Primitives
125+ -- | It is easy to express all the folds in terms of the 'uncons' primitive,
126+ -- however the specific implementations provided later are generally more
127+ -- efficient. Folds are inherently serial as each step needs to use the
128+ -- result of the previous step.
129+ , uncons
130+
107131 -- ** General Folds
108− -- | All the folds can be implemented in terms of 'uncons', however the
109− -- specific implementations provided here are generally more efficient.
110− -- Folds are inherently serial as each step needs to use the result of
111− -- the previous step.
132+-- | Right and left folds.
133+-- As a simple rule, always use lazy right fold for construction and strict
134+-- left fold for reduction. By construction we mean using a constructor as the
135+-- outermost operation in the fold function, by reduction we mean using a
136+-- function as the outermost operation in the fold function.
137+--
138+-- +-----------------------------------+--------------------------------------+
139+-- | Right Fold | Left Fold |
140+-- +===================================+======================================+
141+-- | Construction consumes input | Construction consumes all input, |
142+-- | lazily and streams it in FIFO | and constructs in reverse (LIFO) |
143+-- | order | order |
144+-- +-----------------------------------+--------------------------------------+
145+-- | Reduction ends up buffering all | Strict reduction works |
146+-- | input before it can be reduced | incrementally, without buffering. |
147+-- +-----------------------------------+--------------------------------------+
148+--
149+-- Almost always, we need lazy construction and strict reduction, therefore,
150+-- strict @foldr@ and lazy @foldl@ are rarely useful. If needed, strict @foldr@
151+-- and lazy @foldl@ can be expressed in terms of the available versions. For
152+-- example, a lazy @foldl@ can be replaced by a strict @foldl@ to reverse the
153+-- structure followed by a @foldr@.
154+--
155+-- The following equations may help understand the relation between the two
156+-- folds for lists:
157+--
158+-- @
159+-- foldr f z xs = foldl (flip f) z (reverse xs)
160+-- foldl f z xs = foldr (flip f) z (reverse xs)
161+-- @
162+--
163+-- More generally:
164+--
165+-- @
166+-- foldl f z xs = foldr g id xs z where g x k = k . flip f x
167+-- foldr f z xs = foldl g id xs z where g k x = k . f x
168+-- @
169+
112170 , foldr
113171 , foldr1
114172 , foldrM
@@ -118,108 +176,113 @@ module Streamly.Prelude
118176 , foldx
119177 , foldxM
120178
121− -- ** Specialized Folds
122− -- | These folds can be expressed in terms of the general fold routines but
123− -- the special versions here can be more efficient in many cases.
124−
125− -- Filtering folds: extract parts of the stream
179+ -- ** To Elements
180+ -- | Folds that extract selected elements of a stream or their properties.
181+ , (!!)
126182 , head
127− , tail
128183 , last
129− , init
184+ , findM
185+ , find
186+ , lookup
187+ , findIndex
188+ , elemIndex
130189
131− -- Substreams
132− , isPrefixOf
133− , isSubsequenceOf
134− , stripPrefix
190+ -- ** To Parts
191+ -- | Folds that extract selected parts of a stream.
192+ , tail
193+ , init
135194
136− -- Conditional folds: may terminate early based on a condition
195+ -- ** To Boolean
196+ -- | Folds that summarize the stream to a boolean value.
137197 , null
138198 , elem
139− , elemIndex
140199 , notElem
141− , lookup
142− , findM
143− , find
144− , findIndex
145200 , all
146201 , any
147202 , and
148203 , or
149− , eqBy
150− , cmpBy
151− , (!!)
152− , concatMapM
153− , concatMap
154204
155− -- Full folds - need to go through all elements
205+ -- ** To Summary
206+ -- | Folds that summarize the stream to a single value.
156207 , length
157− , maximum
158− , maximumBy
159− , minimum
160− , minimumBy
161208 , sum
162209 , product
163210
164− -- ** Fold To
211+ -- ** To Summary (Maybe)
212+ -- | Folds that summarize a non-empty stream to a 'Just' value and return
213+ -- 'Nothing' for an empty stream.
214+ , maximumBy
215+ , maximum
216+ , minimumBy
217+ , minimum
218+ , the
219+
220+ -- ** To Containers
165221 -- | Convert or divert a stream into an output structure, container or
166222 -- sink.
167223 , toList
168224 , toHandle
169225
170226 -- * Transformation
171− -- | One to one transformations, each element in the input stream is
172− -- transformed into a corresponding element in the output stream.
173− -- Therefore, the length of the stream and the ordering of elements in the
174− -- stream remains unchanged after the transformation.
175227
176228 -- ** Scanning
177− -- | Scan is a transformation by continuously folding the result with the
178− -- next element of the stream. This is the generalized way to transform a
179− -- stream carrying state from previous transformation steps, other forms of
180− -- transformation like map can be expressed in terms of this.
229+ -- | Scans stream all the intermediate reduction steps of the corresponding
230+ -- folds. The following equations hold for lists:
231+ --
232+ -- > scanl f z xs == map (foldl f z) $ inits xs
233+ -- > scanr f z xs == map (foldr f z) $ tails
234+ --
235+ -- We do not provide a right associative scan, it can be recovered from a
236+ -- 'scanl'' as follows:
237+ --
238+ -- > scanr f z xs == reverse $ scanl' (flip f) z (reverse xs)
239+ --
240+ -- Scan is like a stateful map. If we discard the state, we get the map:
241+ --
242+ -- > S.drop 1 $ S.scanl' (\_ x -> f x) z xs == map f xs
243+
244+ -- > S.postscanl' (\_ x -> f x) z xs == map f xs
245+
181246 , scanl'
182247 , scanlM'
183− , scanlM
184− , scanl
185− , scanl1M'
248+ -- , postscanl'
249+ -- , postscanlM'
250+ -- , prescanl'
251+ -- , prescanlM'
186252 , scanl1'
187− , scanl1M
188− , scanl1
253+ , scanl1M'
189254 , scanx
190255
191256 -- ** Mapping
192− -- | Map is a special form of scan where no state is carried from one step
193− -- to the next.
257+ -- | Map is a strictly one-to-one transformation of stream elements. It
258+ -- cannot add or remove elements from the stream, just transforms them.
194259 , Serial.map
195− , mapM
196260
197261 -- ** Flattening
198262 , sequence
199−
200− -- * Filtering and Insertion
201− -- | Adding or removing elements from the stream thus changing the length
202− -- of the stream.
263+ , mapM
203264
204265 -- ** Filtering
266+ -- | Filtering may remove some elements from the stream.
267+
205268 , filter
206269 , filterM
207− , uniq
208270 , take
209271 , takeWhile
210272 , takeWhileM
211273 , drop
212274 , dropWhile
213275 , dropWhileM
276+ , deleteBy
277+ , uniq
214278
215− -- ** Inserting
216− , intersperseM
217− , insertBy
279+ -- ** Insertion
280+ -- | Insertion adds more elements to the stream.
218281
219− -- ** Deleting
220− , deleteBy
282+ , insertBy
283+ , intersperseM
221284
222− -- * Reordering
285+ -- ** Reordering
223286 , reverse
224287
225288 -- * Hybrid Operations
@@ -234,20 +297,51 @@ module Streamly.Prelude
234297 , findIndices
235298 , elemIndices
236299
237− -- * Zipping
238− , indexed
239− , indexedR
300+ -- * Multi-Stream Operations
301+ -- | New streams can be constructed by appending, merging or zipping
302+ -- existing streams.
303+
304+ -- ** Appending
305+ -- | Streams form a 'Semigroup' and a 'Monoid' under the append
306+ -- operation.
307+ --
308+ -- @
309+ -- >> S.toList $ S.fromList [1,2] \<> S.fromList [3,4]
310+ -- [1,2,3,4]
311+ -- >> S.toList $ fold $ [S.fromList [1,2], S.fromList [3,4]]
312+ -- [1,2,3,4]
313+ -- @
314+
315+ -- ** Merging
316+ -- | Streams form a commutative semigroup under the merge
317+ -- operation.
318+
319+ -- , merge
320+ , mergeBy
321+ , mergeByM
322+ , mergeAsyncBy
323+ , mergeAsyncByM
324+
325+ -- ** Zipping
240326 , zipWith
241327 , zipWithM
242328 , Z.zipAsyncWith
243329 , Z.zipAsyncWithM
244330
245− -- * Merging
246− , mergeBy
247− , merge
331+ -- Special zips
332+ , indexed
333+ , indexedR
248334
249− -- * Transformation comprehensions
250− , the
335+ -- ** Flattening
336+ , concatMapM
337+ , concatMap
338+
339+ -- ** Folds
340+ , eqBy
341+ , cmpBy
342+ , isPrefixOf
343+ , isSubsequenceOf
344+ , stripPrefix
251345
252346 -- * Deprecated
253347 , K.once
@@ -270,6 +364,7 @@ import qualified Prelude
270364import qualified System.IO as IO
271365
272366import Streamly.SVar (MonadAsync, defState, rstState)
367+import Streamly.Streams.Async (mkAsync')
273368import Streamly.Streams.Combinators (maxYields)
274369import Streamly.Streams.Prelude (fromStreamS, toStreamS)
275370import Streamly.Streams.StreamD (fromStreamD, toStreamD)
@@ -306,10 +401,18 @@ uncons m = K.uncons (K.adapt m)
306401-- Generation by Unfolding
307402------------------------------------------------------------------------------
308403
309−-- | Build a stream by unfolding a /pure/ step function starting from a seed.
310−-- The step function returns the next element in the stream and the next seed
311−-- value. When it is done it returns 'Nothing' and the stream ends. For
312−-- example,
404+-- |
405+-- @
406+-- unfoldr step s =
407+-- case step s of
408+-- Nothing -> 'K.nil'
409+-- Just (a, b) -> a \`cons` unfoldr step b
410+-- @
411+--
412+-- Build a stream by unfolding a /pure/ step function @step@ starting from a
413+-- seed @s@. The step function returns the next element in the stream and the
414+-- next seed value. When it is done it returns 'Nothing' and the stream ends.
415+-- For example,
313416--
314417-- @
315418-- let f b =
@@ -322,15 +425,6 @@ uncons m = K.uncons (K.adapt m)
322425-- [0,1,2,3]
323426-- @
324427--
325−-- unfoldr can be expressed in terms of 'yield' and '<>' as follows:
326−--
327−-- @
328−-- unfoldr step s =
329−-- case step s of
330−-- Nothing -> mempty
331−-- Just (a, b) -> 'yield' a '<>' (unfoldr step b)
332−-- @
333−--
334428-- @since 0.1.0
335429{-# INLINE_EARLY unfoldr #-}
336430unfoldr :: (Monad m, IsStream t) => (b -> Maybe (a, b)) -> b -> t m a
@@ -384,20 +478,36 @@ unfoldrMSerial step seed = fromStreamS (S.unfoldrM step seed)
384478
385479-- Faster than yieldM because there is no bind.
386480--
387−-- | Create a singleton stream from a pure value. Same as @a `cons` nil@ but
388−-- slighly more efficient. Note that in monadic streams, 'yield' is the same
389−-- as 'pure' or 'return', however, in Zip applicative streams it is not the
390−-- same as 'pure' because in that case 'pure' is equivalent to 'repeat'
391−-- instead. In all other stream types, 'yield' is the same as @yieldM . pure@
392−-- but more efficient.
481+-- |
482+-- @
483+-- yield a = a \`cons` nil
484+-- @
485+--
486+-- Create a singleton stream from a pure value.
487+--
488+-- The following holds in monadic streams, but not in Zip streams:
489+--
490+-- @
491+-- yield = pure
492+-- yield = yieldM . pure
493+-- @
494+--
495+-- In Zip applicative streams 'yield' is not the same as 'pure' because in that
496+-- case 'pure' is equivalent to 'repeat' instead. 'yield' and 'pure' are
497+-- equally efficient, in other cases 'yield' may be slightly more efficient
498+-- than the other equivalent definitions.
393499--
394500-- @since 0.4.0
395501{-# INLINE yield #-}
396502yield :: IsStream t => a -> t m a
397503yield = K.yield
398504
399−-- | Create a singleton stream from a monadic action. Same as @m \`consM` nil@
400−-- but more efficient.
505+-- |
506+-- @
507+-- yieldM m = m \`consM` nil
508+-- @
509+--
510+-- Create a singleton stream from a monadic action.
401511--
402512-- @
403513-- > toList $ yieldM getLine
@@ -410,24 +520,231 @@ yield = K.yield
410520yieldM :: (Monad m, IsStream t) => m a -> t m a
411521yieldM = K.yieldM
412522
413−-- | Generate a stream of given length, from a given pure
414−-- function of its indices.
415−{-# INLINE generate #-}
416−generate :: (IsStream t, Monad m) => Int -> (Int -> a) -> t m a
417−generate n = fromStreamD . D.generate n
523+-- | @intFromStep from step@ generates an infinite stream whose first element
524+-- is @from@ and the successive elements are in increments of @step@. This does
525+-- not check for overflow or underflow if the 'Integral' type is bounded.
526+--
527+-- @
528+-- > S.toList $ S.take 4 $ S.intFromStep 0 2
529+-- [0,2,4,6]
530+-- > S.toList $ S.take 3 $ S.intFromStep 0 (-2)
531+-- [0,-2,-4]
532+-- @
533+--
534+-- @since 0.6.0
535+{-# INLINE intFromStep #-}
536+intFromStep :: (IsStream t, Monad m, Integral a) => a -> a -> t m a
537+intFromStep from stride = fromStreamD $ D.intFromStep from stride
418538
419−-- | Generate a stream of given length, from a given monadic
420−-- function of its indices.
539+-- | Enumerate an 'Integral' type. @intFrom from@ generates a stream whose
540+-- first element is @from@ and the successive elements are in increments of
541+-- @1@. The stream is bounded by the size of the 'Integral' type.
421542--
422−{-# INLINE generateM #-}
423−generateM :: (IsStream t, Monad m) => Int -> (Int -> m a) -> t m a
424−generateM n = fromStreamD . D.generateM n
543+-- @
544+-- > S.toList $ S.take 4 $ S.intFrom (0 :: Int)
545+-- [0,1,2,3]
546+-- @
547+--
548+-- @since 0.6.0
549+{-# INLINE intFrom #-}
550+intFrom :: (IsStream t, Monad m, Integral a, Bounded a) => a -> t m a
551+intFrom from = fromStreamD $ D.intFrom from
425552
426−-- | Generate a stream by performing a monadic action @n@ times. Can be
427−-- expressed as @stimes n (yieldM m)@.
553+-- | Enumerate an 'Integral' type in steps. @intFromThen from then@ generates a
554+-- stream whose first element is @from@, the second element is @then@ and the
555+-- successive elements are in increments of @then - from@. The stream is
556+-- bounded by the size of the 'Integral' type.
557+--
558+-- @
559+-- > S.toList $ S.take 4 $ S.intFromThen (0 :: Int) 2
560+-- [0,2,4,6]
561+-- > S.toList $ S.take 4 $ S.intFromThen (0 :: Int) (-2)
562+-- [0,-2,-4,-6]
563+-- @
564+--
565+-- @since 0.6.0
566+{-# INLINE intFromThen #-}
567+intFromThen :: (IsStream t, Monad m, Integral a, Bounded a) => a -> a -> t m a
568+intFromThen from next = fromStreamD $ D.intFromThen from next
569+
570+-- | Enumerate an 'Integral' type up to a given limit. @intFromTo from to@
571+-- generates a finite stream whose first element is @from@ and successive
572+-- elements are in increments of @1@ up to @to@.
573+--
574+-- @
575+-- > S.toList $ S.intFromTo 0 4
576+-- [0,1,2,3,4]
577+-- @
578+--
579+-- @since 0.6.0
580+{-# INLINE intFromTo #-}
581+intFromTo :: (IsStream t, Monad m, Integral a) => a -> a -> t m a
582+intFromTo from to = fromStreamD $ D.intFromTo from to
583+
584+-- | Enumerate an 'Integral' type in steps up to a given limit. @intFromThenTo
585+-- from then to@ generates a finite stream whose first element is @from@, the
586+-- second element is @then@ and the successive elements are in increments of
587+-- @then - from@ up to @to@.
588+--
589+-- @
590+-- > S.toList $ S.intFromThenTo 0 2 6
591+-- [0,2,4,6]
592+-- > S.toList $ S.intFromThenTo 0 (-2) (-6)
593+-- [0,-2,-4,-6]
594+-- @
595+--
596+-- @since 0.6.0
597+{-# INLINE intFromThenTo #-}
598+intFromThenTo :: (IsStream t, Monad m, Integral a) => a -> a -> a -> t m a
599+intFromThenTo from next to = fromStreamD $ D.intFromThenTo from next to
600+
601+-- | @numFromStep from step@ generates an infinite stream whose first element
602+-- is @from@ and the successive elements are in increments of @step@. This is
603+-- numerically stable but does not check for overflow or underflow for bounded
604+-- types. Note, for 'Integral' types 'intFromStep' is faster.
428605--
429606--
430607-- @
608+-- > S.toList $ S.take 4 $ S.numFromStep 0.1 2
609+-- [0.1,2.1,4.1,6.1]
610+-- > S.toList $ S.take 3 $ S.numFromStep 0.1 (-2)
611+-- [0.1,-1.9,-3.9,-5.9]
612+-- @
613+--
614+-- @since 0.6.0
615+{-# INLINE numFromStep #-}
616+numFromStep :: (IsStream t, Monad m, Num a) => a -> a -> t m a
617+numFromStep from stride = fromStreamD $ D.numFromStep from stride
618+
619+-- Even though the underlying implementation of fracFrom and fracFromThen works
620+-- for any 'Num' we have restricted these to 'Fractional' because these do not
621+-- perform any bounds check, in contrast to int versions and are therefore not
622+-- equivalent substitutes for those.
623+--
624+-- | Numerically stable enumeration from a 'Fractional' number in steps of size
625+-- @1@. @fracFrom from@ generates a stream whose first element is @from@ and
626+-- the successive elements are in increments of @1@. No overflow or underflow
627+-- checks are performed.
628+--
629+-- This is the equivalent to 'enumFrom' for 'Fractional' types. For example:
630+--
631+-- @
632+-- > S.toList $ S.take 4 $ S.fracFrom 1.1
633+-- [1.1,2.1,3.1,4.1]
634+-- @
635+--
636+--
637+-- @since 0.6.0
638+{-# INLINE fracFrom #-}
639+fracFrom :: (IsStream t, Monad m, Fractional a) => a -> t m a
640+fracFrom from = fromStreamD $ D.numFrom from
641+
642+-- | Numerically stable enumeration from a 'Fractional' number in steps.
643+-- @fracFromThen from then@ generates a stream whose first element is @from@,
644+-- the second element is @then@ and the successive elements are in increments
645+-- of @then - from@. No overflow or underflow checks are performed.
646+--
647+-- This is the equivalent of 'enumFromThen' for 'Fractional' types. For
648+-- example:
649+--
650+-- @
651+-- > S.toList $ S.take 4 $ S.fracFromThen 1.1 2.1
652+-- [1.1,2.1,3.1,4.1]
653+-- > S.toList $ S.take 4 $ S.fracFromThen 1.1 (-2.1)
654+-- [1.1,-2.1,-5.300000000000001,-8.500000000000002]
655+-- @
656+--
657+-- @since 0.6.0
658+{-# INLINE fracFromThen #-}
659+fracFromThen :: (IsStream t, Monad m, Fractional a) => a -> a -> t m a
660+fracFromThen from next = fromStreamD $ D.numFromThen from next
661+
662+-- | Numerically stable enumeration from a 'Fractional' number to a given
663+-- limit. @fracFromTo from to@ generates a finite stream whose first element
664+-- is @from@ and successive elements are in increments of @1@ up to @to@.
665+--
666+-- This is the equivalent of 'enumFromTo' for 'Fractional' types. For
667+-- example:
668+--
669+-- @
670+-- > S.toList $ S.fracFromTo 1.1 4
671+-- [1.1,2.1,3.1,4.1]
672+-- > S.toList $ S.fracFromTo 1.1 4.6
673+-- [1.1,2.1,3.1,4.1,5.1]
674+-- @
675+--
676+-- Notice that the last element is equal to the specified @to@ value after
677+-- rounding to the nearest integer.
678+--
679+-- @since 0.6.0
680+{-# INLINE fracFromTo #-}
681+fracFromTo :: (IsStream t, Monad m, Fractional a, Ord a) => a -> a -> t m a
682+fracFromTo from to = fromStreamD $ D.fracFromTo from to
683+
684+-- | Numerically stable enumeration from a 'Fractional' number in steps up to a
685+-- given limit. @fracFromThenTo from then to@ generates a finite stream whose
686+-- first element is @from@, the second element is @then@ and the successive
687+-- elements are in increments of @then - from@ up to @to@.
688+--
689+-- This is the equivalent of 'enumFromThenTo' for 'Fractional' types. For
690+-- example:
691+--
692+-- @
693+-- > S.toList $ S.fracFromThenTo 0.1 2 6
694+-- [0.1,2.0,3.9,5.799999999999999]
695+-- > S.toList $ S.fracFromThenTo 0.1 (-2) (-6)
696+-- [0.1,-2.0,-4.1000000000000005,-6.200000000000001]
697+-- @
698+--
699+--
700+-- @since 0.6.0
701+{-# INLINE fracFromThenTo #-}
702+fracFromThenTo
703+ :: (IsStream t, Monad m, Fractional a, Ord a)
704+ => a -> a -> a -> t m a
705+fracFromThenTo from next to = fromStreamD $ D.fracFromThenTo from next to
706+
707+-- |
708+-- @
709+-- fromIndices f = let g i = f i \`cons` g (i + 1) in g 0
710+-- @
711+--
712+-- Generate an infinite stream, whose values are the output of a function @f@
713+-- applied on the corresponding index. Index starts at 0.
714+--
715+-- @
716+-- > S.toList $ S.take 5 $ S.fromIndices id
717+-- [0,1,2,3,4]
718+-- @
719+--
720+-- @since 0.6.0
721+{-# INLINE fromIndices #-}
722+fromIndices :: (IsStream t, Monad m) => (Int -> a) -> t m a
723+fromIndices = fromStreamD . D.fromIndices
724+
725+-- XXX this needs to be concurrent
726+--
727+-- |
728+-- @
729+-- fromIndicesM f = let g i = f i \`consM` g (i + 1) in g 0
730+-- @
731+--
732+-- Generate an infinite stream, whose values are the output of a monadic
733+-- function @f@ applied on the corresponding index. Index starts at 0.
734+--
735+-- @since 0.6.0
736+{-# INLINE fromIndicesM #-}
737+fromIndicesM :: (IsStream t, Monad m) => (Int -> m a) -> t m a
738+fromIndicesM = fromStreamD . D.fromIndicesM
739+
740+-- |
741+-- @
742+-- replicateM = take n . repeatM
743+-- @
744+--
745+-- Generate a stream by performing a monadic action @n@ times. Same as:
746+--
747+-- @
431748-- runStream $ serially $ S.replicateM 10 $ (threadDelay 1000000 >> print 1)
432749-- runStream $ asyncly $ S.replicateM 10 $ (threadDelay 1000000 >> print 1)
433750-- @
@@ -435,20 +752,33 @@ generateM n = fromStreamD . D.generateM n
435752-- /Concurrent/
436753--
437754-- @since 0.1.1
755+{-# INLINE_EARLY replicateM #-}
438756replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
439−replicateM n m = go n
440− where
441− go cnt = if cnt <= 0 then K.nil else m |: go (cnt - 1)
757+replicateM = K.replicateM
758+
759+{-# RULES "replicateM serial" replicateM = replicateMSerial #-}
760+{-# INLINE replicateMSerial #-}
761+replicateMSerial :: MonadAsync m => Int -> m a -> SerialT m a
762+replicateMSerial n = fromStreamS . S.replicateM n
442763
443−-- | Generate a stream by replicating the value @n@ times.
764+-- |
765+-- @
766+-- replicate = take n . repeat
767+-- @
444768--
445−replicate :: IsStream t => Int -> a -> t m a
446−replicate n a = go n
447− where
448− go cnt = if cnt <= 0 then K.nil else a `K.cons` go (cnt - 1)
769+-- Generate a stream of length @n@ by repeating a value @n@ times.
770+--
771+-- @since 0.6.0
772+replicate :: (IsStream t, Monad m) => Int -> a -> t m a
773+replicate n = fromStreamS . S.replicate n
449774
450−-- | Generate a stream by repeatedly executing a monadic action forever. Can be
451−-- expressed as @cycle1 . yieldM@.
775+-- |
776+-- @
777+-- repeatM = fix . consM
778+-- repeatM = cycle1 . yieldM
779+-- @
780+--
781+-- Generate a stream by repeatedly executing a monadic action forever.
452782--
453783-- @
454784-- runStream $ serially $ S.take 10 $ S.repeatM $ (threadDelay 1000000 >> print 1)
@@ -462,7 +792,19 @@ repeatM :: (IsStream t, MonadAsync m) => m a -> t m a
462792repeatM = go
463793 where go m = m |: go m
464794
465−-- | Iterate a pure function from a seed value, streaming the results forever.
795+-- |
796+-- @
797+-- iterate f x = x \`cons` iterate f x
798+-- @
799+--
800+-- Generate an infinite stream with @x@ as the first element and each
801+-- successive element derived by applying the function @f@ on the previous
802+-- element.
803+--
804+-- @
805+-- > S.toList $ S.take 5 $ S.iterate (+1) 1
806+-- [1,2,3,4,5]
807+-- @
466808--
467809-- @since 0.1.2
468810iterate :: IsStream t => (a -> a) -> a -> t m a
@@ -470,8 +812,14 @@ iterate step = fromStream . go
470812 where
471813 go s = K.cons s (go (step s))
472814
473−-- | Iterate a monadic function from a seed value, streaming the results
474−-- forever.
815+-- |
816+-- @
817+-- iterateM f m = m \`consM` iterateM f m
818+-- @
819+--
820+-- Generate an infinite stream with the first element generated by the action
821+-- @m@ and each successive element derived by applying the monadic function
822+-- @f@ on the previous element.
475823--
476824-- When run concurrently, the next iteration can run concurrently with the
477825-- processing of the previous iteration. Note that more than one iteration
@@ -500,9 +848,13 @@ iterateM step = go
500848-- Conversions
501849------------------------------------------------------------------------------
502850
503−-- | Construct a stream from a list containing monadic actions. More efficient
504−-- list specific implementation of 'fromFoldableM' especially for serial
505−-- streams as it works well with fusion optimization.
851+-- |
852+-- @
853+-- fromListM = 'Prelude.foldr' 'K.consM' 'K.nil'
854+-- @
855+--
856+-- Construct a stream from a list of monadic actions. This is more efficient
857+-- than 'fromFoldableM' for serial streams.
506858--
507859-- @since 0.4.0
508860{-# INLINE_EARLY fromListM #-}
@@ -511,8 +863,12 @@ fromListM = fromStreamD . D.fromListM
511863{-# RULES "fromListM fallback to StreamK" [1]
512864 forall a. D.toStreamK (D.fromListM a) = fromFoldableM a #-}
513865
514−-- | Construct a stream from a 'Foldable' containing monadic actions. Same as
515−-- @'Prelude.foldr' 'consM' 'K.nil'@.
866+-- |
867+-- @
868+-- fromFoldableM = 'Prelude.foldr' 'consM' 'K.nil'
869+-- @
870+--
871+-- Construct a stream from a 'Foldable' containing monadic actions.
516872--
517873-- @
518874-- runStream $ serially $ S.fromFoldableM $ replicateM 10 (threadDelay 1000000 >> print 1)
@@ -556,7 +912,7 @@ fromHandle h = fromStream go
556912-- stream into a list:
557913--
558914-- @
559−-- >> runIdentity $ foldrM (\\x xs -> return (x : xs)) [] (serially $ fromFoldable [1,2,3])
915+-- >> S.foldrM (\\x xs -> return (x : xs)) [] $ fromList [1,2,3]
560916-- [1,2,3]
561917-- @
562918--
@@ -565,19 +921,74 @@ fromHandle h = fromStream go
565921foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
566922foldrM = P.foldrM
567923
568−-- | Lazy right associative fold. For example, to fold a stream into a list:
924+-- | Lazy right associative fold.
925+--
926+-- @foldr f z xs@ deconstructs @xs@ one element @x@ at a time, applying the
927+-- function @f@ to @x@ and the tail of the output. The tail recurses until the
928+-- input finishes and @z@ is used as the tail end.
569929--
570930-- @
571−-- >> runIdentity $ foldr (:) [] (serially $ fromFoldable [1,2,3])
572−-- [1,2,3]
931+-- foldr f z xs == x1 \`f` tail1
932+-- tail1 == x2 \`f` tail2
933+-- tail2 == x3 \`f` tail3
934+-- ...
935+-- tailn == xn \`f` z
573936-- @
574937--
938+-- Resulting in a right associated expression:
939+--
940+-- @
941+-- foldr f z xs == x1 \`f` (x2 \`f` ...(xn \`f` z))
942+-- @
943+--
944+-- When the outermost operation in the fold function is a constructor, foldr
945+-- generates a structure that can be consumed lazily. For example:
946+--
947+-- @
948+-- > S.foldr (:) [] $ S.fromList [1,2,3,4]
949+-- [1,2,3,4]
950+-- @
951+--
952+-- @
953+-- 1 : tail
954+-- 1 : (2 : tail)
955+-- 1 : (2 : (3 : tail))
956+-- 1 : (2 : (3 : (4 : [])))
957+-- @
958+--
959+-- When the outermost operation is a function @foldr@ results in a right
960+-- associated expression which cannot be reduced until the whole expression has
961+-- been built. Therefore, it ends up consuming the whole input, buffering the
962+-- whole expression in memory before reduction can start. For example:
963+--
964+-- @
965+-- > S.foldr (+) 0 $ S.fromList [1,2,3,4]
966+-- 10
967+-- @
968+--
969+-- @
970+-- 1 + tail
971+-- 1 + (2 + tail)
972+-- 1 + (2 + (3 + tail))
973+-- 1 + (2 + (3 + (4 + 0)))
974+-- @
975+--
976+-- In @foldr@, the output tail is the source of recursion, we can stop
977+-- recursion and terminate the fold by yielding a terminal value as tail:
978+--
979+-- >> S.foldr (\x rest -> if x == 3 then [] else x : rest) [] $ S.fromList [4,1,3,undefined]
980+-- >[4,1]
981+--
982+-- The arguments to the folding function (@a -> b -> b@) are in the head and
983+-- tail order of the output, @a@ is the head and @b@ is the tail. Remember, in
984+-- a right fold the zero is on the right, it is the tail end.
985+--
575986-- @since 0.1.0
576987{-# INLINE foldr #-}
577988foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
578989foldr = P.foldr
579990
580−-- | Right fold, for non-empty streams, using first element as the starting
991+-- | Lazy right fold for non-empty streams, using first element as the starting
581992-- value. Returns 'Nothing' if the stream is empty.
582993--
583994-- @since 0.5.0
@@ -603,6 +1014,85 @@ foldl = foldx
6031014
6041015-- | Strict left associative fold.
6051016--
1017+-- @foldl' f z xs@ deconstructs @xs@ one element @x@ at a time, applying the
1018+-- function @f@ to the output accumulated till now (the head of the expression)
1019+-- and @x@. The accumulator starts with the initial value @z@ and keeps
1020+-- accumulating elements until the input finishes.
1021+--
1022+-- @
1023+-- head1 == z \`f` x1
1024+-- head2 == head1 \`f` x2
1025+-- head3 == head2 \`f` x3
1026+-- ...
1027+-- foldl' f z xs == head(n-1) \`f` xn
1028+-- @
1029+--
1030+-- Recursively building a left associated expression:
1031+--
1032+-- @
1033+-- foldl' f z xs == (((z \`f` x1) \`f` x2) ...) \`f` xn
1034+-- @
1035+--
1036+-- When the outermost operation in the fold function is a (left associated)
1037+-- constructor, foldl' consumes the whole input to construct the new structure
1038+-- buffered in memory in the reverse order of the input. For example:
1039+--
1040+-- @
1041+-- > S.foldl' (flip (:)) [] $ S.fromList [1,2,3,4]
1042+-- [4,3,2,1]
1043+-- @
1044+--
1045+-- When the outermost operation is a function, @foldl'@ results in a left
1046+-- associated expression which is incrementally reduced at each step of the
1047+-- fold, thus never building the whole expression in memory. For example:
1048+--
1049+-- @
1050+-- > S.foldl' (+) 0 $ S.fromList [1,2,3,4]
1051+-- 10
1052+-- @
1053+--
1054+-- @
1055+-- 0 + 1
1056+-- (0 + 1) + 2
1057+-- ((0 + 1) + 2) + 3
1058+-- (((0 + 1) + 2) + 3) + 4
1059+-- @
1060+-- @
1061+-- 0 + 1 => reduce to 1
1062+-- 1 + 2 => reduce to 3
1063+-- 3 + 3 => reduce to 6
1064+-- 6 + 4 => reduce to 10
1065+-- @
1066+--
1067+-- We can stop recursion and terminate the fold by yielding an expression that
1068+-- is independent of the input element:
1069+--
1070+-- >> S.foldl' (\acc x -> if acc >= 8 then acc else x + acc) 0 $ S.fromList [4,1,3,undefined]
1071+-- >8
1072+--
1073+-- To stop on encountering the number 3 we will have to store the previous
1074+-- number in the accumulator so that we do not depend on the current input:
1075+--
1076+-- @
1077+-- > S.foldl' (\(acc, prev) x -> if prev == 3 then (acc,prev) else (x + acc,x))
1078+-- (0,0) $ S.fromList \[4,1,3,undefined]
1079+-- (8,3)
1080+-- @
1081+--
1082+-- To map the fold operation to stateful or event-driven programming, we can
1083+-- consider @z@ as the initial state and the stream being folded as a stream of
1084+-- events, thus @foldl'@ processes all the events in the stream updating the
1085+-- state on each event and then ultimately returning the final state.
1086+--
1087+-- The arguments to the folding function (@b -> a -> b@) are in the head and
1088+-- tail order of the output expression, @b@ is the head and @a@ is the tail.
1089+-- Remember, in a left fold the zero is on the left, at the head of the
1090+-- expression.
1091+--
1092+-- IMPORTANT: 'foldl'' evaluates the accumulator to WHNF. To avoid building
1093+-- lazy expressions inside the accumulator, and to help GHC optimize better, it
1094+-- is recommended that a strict data structure is used for accumulator.
1095+--
6061096-- @since 0.2.0
6071097{-# INLINE foldl' #-}
6081098foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
@@ -622,7 +1112,6 @@ foldl1' step m = do
6221112 res <- foldl' step h t
6231113 return $ Just res
6241114
625−-- XXX replace the recursive "go" with explicit continuations.
6261115-- | Like 'foldx', but with a monadic step function.
6271116--
6281117-- @since 0.2.0
@@ -654,6 +1143,8 @@ null = K.null
6541143
6551144-- | Extract the first element of the stream, if any.
6561145--
1146+-- > head = (!! 0)
1147+--
6571148-- @since 0.1.0
6581149{-# INLINE head #-}
6591150head :: Monad m => SerialT m a -> m (Maybe a)
@@ -675,6 +1166,8 @@ init m = K.init (K.adapt m)
6751166
6761167-- | Extract the last element of the stream, if any.
6771168--
1169+-- > last xs = xs !! (length xs - 1)
1170+--
6781171-- @since 0.1.1
6791172{-# INLINE last #-}
6801173last :: Monad m => SerialT m a -> m (Maybe a)
@@ -722,75 +1215,99 @@ any p m = S.any p (toStreamS m)
7221215and :: Monad m => SerialT m Bool -> m Bool
7231216and = all (==True)
7241217
725−-- | Determines wheter at least one element of a boolean stream is True.
1218+-- | Determines whether at least one element of a boolean stream is True.
7261219--
7271220-- @since 0.5.0
7281221{-# INLINE or #-}
7291222or :: Monad m => SerialT m Bool -> m Bool
7301223or = any (==True)
7311224
732−-- | Determine the sum of all elements of a stream of numbers
1225+-- | Determine the sum of all elements of a stream of numbers. Returns @0@ when
1226+-- the stream is empty. Note that this is not numerically stable for floating
1227+-- point numbers.
7331228--
7341229-- @since 0.1.0
7351230{-# INLINE sum #-}
7361231sum :: (Monad m, Num a) => SerialT m a -> m a
7371232sum = foldl' (+) 0
7381233
739−-- | Determine the product of all elements of a stream of numbers
1234+-- | Determine the product of all elements of a stream of numbers. Returns @1@
1235+-- when the stream is empty.
7401236--
7411237-- @since 0.1.1
7421238{-# INLINE product #-}
7431239product :: (Monad m, Num a) => SerialT m a -> m a
7441240product = foldl' (*) 1
7451241
746−-- | Determine the minimum element in a stream.
1242+-- |
1243+-- @
1244+-- minimum = 'minimumBy' compare
1245+-- @
1246+--
1247+-- Determine the minimum element in a stream.
7471248--
7481249-- @since 0.1.0
7491250{-# INLINE minimum #-}
7501251minimum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
7511252minimum m = S.minimum (toStreamS m)
7521253
753−-- | Non-overloaded version of minimum.
1254+-- | Determine the minimum element in a stream using the supplied comparison
1255+-- function.
7541256--
1257+-- @since 0.6.0
7551258{-# INLINE minimumBy #-}
7561259minimumBy :: Monad m => (a -> a -> Ordering) -> SerialT m a -> m (Maybe a)
7571260minimumBy cmp m = S.minimumBy cmp (toStreamS m)
7581261
759−-- | Determine the maximum element in a stream.
1262+-- |
1263+-- @
1264+-- maximum = 'maximumBy' compare
1265+-- @
1266+--
1267+-- Determine the maximum element in a stream.
7601268--
1269+-- @since 0.1.0
7611270{-# INLINE maximum #-}
7621271maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
7631272maximum m = S.maximum (toStreamS m)
7641273
765−-- | Non-overloaded version of maximum.
1274+-- | Determine the maximum element in a stream using the supplied comparison
1275+-- function.
7661276--
1277+-- @since 0.6.0
7671278{-# INLINE maximumBy #-}
7681279maximumBy :: Monad m => (a -> a -> Ordering) -> SerialT m a -> m (Maybe a)
7691280maximumBy cmp m = S.maximumBy cmp (toStreamS m)
7701281
771−-- | Looks the element at the given index.
1282+-- | Lookup the element at the given index.
7721283--
1284+-- @since 0.6.0
7731285{-# INLINE (!!) #-}
7741286(!!) :: Monad m => SerialT m a -> Int -> m (Maybe a)
775−m !! i = (toStreamS m) S.!! i
1287+m !! i = toStreamS m S.!! i
7761288
777−-- | Looks the given key up, treating the given stream as an association list.
1289+-- | In a stream of (key-value) pairs @(a, b)@, return the value @b@ of the
1290+-- first pair where the key equals the given value @a@.
1291+--
1292+-- > lookup = snd <$> find ((==) . fst)
7781293--
7791294-- @since 0.5.0
7801295{-# INLINE lookup #-}
7811296lookup :: (Monad m, Eq a) => a -> SerialT m (a, b) -> m (Maybe b)
7821297lookup a m = S.lookup a (toStreamS m)
7831298
784−-- | Returns the first element of the stream satisfying the given predicate,
785−-- if any.
1299+-- | Like 'findM' but with a non-monadic predicate.
1300+--
1301+-- > find p = findM (return . p)
7861302--
7871303-- @since 0.5.0
7881304{-# INLINE find #-}
7891305find :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe a)
7901306find p m = S.find p (toStreamS m)
7911307
792−-- | Like 'find' but with a monadic predicate.
1308+-- | Returns the first element that satisfies the given predicate.
7931309--
1310+-- @since 0.6.0
7941311{-# INLINE findM #-}
7951312findM :: Monad m => (a -> m Bool) -> SerialT m a -> m (Maybe a)
7961313findM p m = S.findM p (toStreamS m)
@@ -803,8 +1320,7 @@ findM p m = S.findM p (toStreamS m)
8031320findIndices :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m Int
8041321findIndices p m = fromStreamS $ S.findIndices p (toStreamS m)
8051322
806−-- | Gives the index of the first stream element satisfying the given
807−-- preficate.
1323+-- | Returns the first index that satisfies the given predicate.
8081324--
8091325-- @since 0.5.0
8101326{-# INLINE findIndex #-}
@@ -819,46 +1335,74 @@ findIndex p = head . findIndices p
8191335elemIndices :: (IsStream t, Eq a, Monad m) => a -> t m a -> t m Int
8201336elemIndices a = findIndices (==a)
8211337
822−-- | Gives the first index of an element in the stream, which equals the given.
1338+-- | Returns the first index where a given value is found in the stream.
1339+--
1340+-- > elemIndex a = findIndex (== a)
8231341--
8241342-- @since 0.5.0
8251343{-# INLINE elemIndex #-}
8261344elemIndex :: (Monad m, Eq a) => a -> SerialT m a -> m (Maybe Int)
827−elemIndex a = findIndex (==a)
1345+elemIndex a = findIndex (== a)
8281346
1347+-- | Map each element to a stream and then flatten the results into a single
1348+-- stream.
1349+--
1350+-- > concatMap f = concatMapM (return . f)
1351+--
1352+-- @since 0.6.0
8291353{-# INLINE concatMap #-}
830−concatMap :: Monad m => (a -> SerialT m b) -> SerialT m a -> SerialT m b
1354+concatMap ::(IsStream t, Monad m) => (a -> t m b) -> t m a -> t m b
8311355concatMap f m = fromStreamD $ D.concatMap (toStreamD . f) (toStreamD m)
8321356
1357+-- | Map each element to a stream using a monadic function and then flatten the
1358+-- results into a single stream.
1359+--
1360+-- @since 0.6.0
8331361{-# INLINE concatMapM #-}
834−concatMapM :: Monad m => (a -> m (SerialT m b)) -> SerialT m a -> SerialT m b
1362+concatMapM :: (IsStream t, Monad m) => (a -> m (t m b)) -> t m a -> t m b
8351363concatMapM f m = fromStreamD $ D.concatMapM (fmap toStreamD . f) (toStreamD m)
8361364
8371365------------------------------------------------------------------------------
8381366-- Substreams
8391367------------------------------------------------------------------------------
8401368
841−-- | Takes two streams and returns 'True' iff the first stream is a prefix
842−-- of the second.
1369+-- | Returns 'True' if the first stream is the same as or a prefix of the
1370+-- second.
1371+--
1372+-- @
1373+-- > S.isPrefixOf (S.fromList "hello") (S.fromList "hello" :: SerialT IO Char)
1374+-- True
1375+-- @
8431376--
1377+-- @since 0.6.0
8441378{-# INLINE isPrefixOf #-}
8451379isPrefixOf :: (Eq a, IsStream t, Monad m) => t m a -> t m a -> m Bool
8461380isPrefixOf m1 m2 = D.isPrefixOf (toStreamD m1) (toStreamD m2)
8471381
848−-- | Takes two streams and returns 'True' if all the elements of the
849−-- first stream occur, in order, in the second stream. The elements do
850−-- not have to occur consecutively.
1382+-- | Returns 'True' if all the elements of the first stream occur, in order, in
1383+-- the second stream. The elements do not have to occur consecutively. A stream
1384+-- is treated as a subsequence of itself.
1385+--
1386+-- @
1387+-- > S.isSubsequenceOf (S.fromList "hlo") (S.fromList "hello" :: SerialT IO Char)
1388+-- True
1389+-- @
8511390--
1391+-- @since 0.6.0
8521392{-# INLINE isSubsequenceOf #-}
8531393isSubsequenceOf :: (Eq a, IsStream t, Monad m) => t m a -> t m a -> m Bool
8541394isSubsequenceOf m1 m2 = D.isSubsequenceOf (toStreamD m1) (toStreamD m2)
8551395
856−-- | Drops the given prefix from a stream. Returns Nothing if the stream
857−-- doesn't start with the prefix given.
1396+-- | Drops the given prefix from a stream. Returns 'Nothing' if the stream does
1397+-- not start with the given prefix. Returns @Just nil@ when the prefix is the
1398+-- same as the stream.
8581399--
1400+-- @since 0.6.0
8591401{-# INLINE stripPrefix #-}
860−stripPrefix :: (Eq a, IsStream t, Monad m) => t m a -> t m a -> m (Maybe (t m a))
861−stripPrefix m1 m2 = fmap (fmap fromStreamD) $
1402+stripPrefix
1403+ :: (Eq a, IsStream t, Monad m)
1404+ => t m a -> t m a -> m (Maybe (t m a))
1405+stripPrefix m1 m2 = fmap fromStreamD <$>
8621406 D.stripPrefix (toStreamD m1) (toStreamD m2)
8631407
8641408------------------------------------------------------------------------------
@@ -878,14 +1422,24 @@ mapM_ f m = S.mapM_ f $ toStreamS m
8781422-- Conversions
8791423------------------------------------------------------------------------------
8801424
881−-- | Convert a stream into a list in the underlying monad.
1425+-- |
1426+-- @
1427+-- toList = S.foldr (:) []
1428+-- @
1429+--
1430+-- Convert a stream into a list in the underlying monad. Same as:
8821431--
8831432-- @since 0.1.0
8841433{-# INLINE toList #-}
8851434toList :: Monad m => SerialT m a -> m [a]
8861435toList = P.toList
8871436
888−-- | Write a stream of Strings to an IO Handle.
1437+-- |
1438+-- @
1439+-- toHandle h = S.mapM_ $ hPutStrLn h
1440+-- @
1441+--
1442+-- Write a stream of Strings to an IO Handle.
8891443--
8901444-- @since 0.1.0
8911445toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
@@ -917,56 +1471,116 @@ scanx = K.scanx
9171471scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
9181472scan = scanx
9191473
920−-- | Like 'scanl'' but with a monadic step function.
1474+-- XXX this needs to be concurrent
1475+-- | Like 'scanl'' but with a monadic fold function.
9211476--
9221477-- @since 0.4.0
9231478{-# INLINE scanlM' #-}
9241479scanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> t m b
9251480scanlM' step begin m = fromStreamD $ D.scanlM' step begin $ toStreamD m
9261481
927−-- | Strict left scan. Like 'foldl'', but returns the folded value at each
928−-- step, generating a stream of all intermediate fold results. The first
929−-- element of the stream is the user supplied initial value, and the last
930−-- element of the stream is the same as the result of 'foldl''.
1482+-- | Strict left scan.
1483+--
1484+-- @
1485+-- > S.toList $ S.scanl' (+) 0 $ fromList [1,2,3,4]
1486+-- [0,1,3,6,10]
1487+-- @
1488+--
1489+-- @
1490+-- > S.toList $ S.scanl' (flip (:)) [] $ S.fromList [1,2,3,4]
1491+-- [[],[1],[2,1],[3,2,1],[4,3,2,1]]
1492+-- @
1493+--
1494+-- The output of 'scanl'' is the initial value of the accumulator followed by
1495+-- all the intermediate steps and the final result of 'foldl''.
1496+--
1497+-- By streaming the accumulated state after each fold step, we can share the
1498+-- state across multiple stages of stream composition. Each stage can modify or
1499+-- extend the state, do some processing with it and emit it for the next stage,
1500+-- thus modularizing the stream processing. This can be useful in
1501+-- stateful or event-driven programming.
1502+--
1503+-- Consider the following example, computing the sum and the product of the
1504+-- elements in a stream in one go using a @foldl'@:
1505+--
1506+-- @
1507+-- > S.foldl' (\\(s, p) x -> (s + x, p * x)) (0,1) $ S.fromList \[1,2,3,4]
1508+-- (10,24)
1509+-- @
1510+--
1511+-- Using @scanl'@ we can compute the sum in the first stage and pass it down to
1512+-- the next stage for computing the product:
1513+--
1514+-- @
1515+-- > S.foldl' (\\(_, p) (s, x) -> (s, p * x)) (0,1)
1516+-- $ S.scanl' (\\(s, _) x -> (s + x, x)) (0,1)
1517+-- $ S.fromList \[1,2,3,4]
1518+-- (10,24)
1519+-- @
1520+--
1521+-- IMPORTANT: 'scanl'' evaluates the accumulator to WHNF. To avoid building
1522+-- lazy expressions inside the accumulator, and to help GHC optimize better, it
1523+-- is recommended that a strict data structure is used for accumulator.
9311524--
9321525-- @since 0.2.0
9331526{-# INLINE scanl' #-}
9341527scanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
9351528scanl' step z m = fromStreamS $ S.scanl' step z $ toStreamS m
9361529
937−-- | Like 'scanlM'' but with a non-strict accumulator.
1530+-- XXX enable once the signature (monadic zero) change is settled
1531+-- | Like scanl' but does not stream the initial value of the accumulator.
9381532--
939−{-# INLINE scanlM #-}
940−scanlM :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> t m b
941−scanlM step begin m = fromStreamD $ D.scanlM step begin $ toStreamD m
1533+-- > postscanl' f z xs = S.drop 1 $ scanl' f z xs
1534+--
1535+-- @since 0.6.0
1536+{-# INLINE _postscanl' #-}
1537+_postscanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
1538+_postscanl' step z m = fromStreamD $ D.postscanl' step z $ toStreamD m
1539+
1540+-- XXX this needs to be concurrent
1541+-- | Like postscanl' but with a monadic step function.
1542+--
1543+-- @since 0.6.0
1544+{-# INLINE _postscanlM' #-}
1545+_postscanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> t m b
1546+_postscanlM' step z m = fromStreamD $ D.postscanlM' step z $ toStreamD m
9421547
943−-- | Like 'scanl'' but with a non-strict accumulator.
944−{-# INLINE scanl #-}
945−scanl :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
946−scanl step z m = fromStreamD $ D.scanl step z $ toStreamD m
1548+-- XXX prescanl does not sound very useful, enable only if there is a
1549+-- compelling use case.
1550+--
1551+-- | Like scanl' but does not stream the final value of the accumulator.
1552+--
1553+-- @since 0.6.0
1554+{-# INLINE _prescanl' #-}
1555+_prescanl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> t m b
1556+_prescanl' step z m = fromStreamD $ D.prescanl' step z $ toStreamD m
9471557
948−-- | Left scan with a monadic step function. Uses the first element of
949−-- the stream as the starting value. Returns an empty stream if the
950−-- given stream is empty.
1558+-- XXX this needs to be concurrent
1559+-- | Like postscanl' but with a monadic step function.
9511560--
952−{-# INLINE scanl1M #-}
953−scanl1M :: (IsStream t, Monad m) => (a -> a -> m a) -> t m a -> t m a
954−scanl1M step m = fromStreamD $ D.scanl1M step $ toStreamD m
1561+-- @since 0.6.0
1562+{-# INLINE _prescanlM' #-}
1563+_prescanlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> m b -> t m a -> t m b
1564+_prescanlM' step z m = fromStreamD $ D.prescanlM' step z $ toStreamD m
9551565
956−-- | Like 'scanl1M' but with a strict accumulator.
1566+-- XXX this needs to be concurrent
1567+-- | Like 'scanl1'' but with a monadic step function.
9571568--
1569+-- @since 0.6.0
9581570{-# INLINE scanl1M' #-}
9591571scanl1M' :: (IsStream t, Monad m) => (a -> a -> m a) -> t m a -> t m a
9601572scanl1M' step m = fromStreamD $ D.scanl1M' step $ toStreamD m
9611573
962−-- | Left scan, uses the first element of the stream as the starting
963−-- value. Returns an empty stream if the given stream is empty.
964−{-# INLINE scanl1 #-}
965−scanl1 :: (IsStream t, Monad m) => (a -> a -> a) -> t m a -> t m a
966−scanl1 step m = fromStreamD $ D.scanl1 step $ toStreamD m
967−
968−-- | Like 'scanl1'' but with a strict accumulator.
1574+-- | Like 'scanl'' but for a non-empty stream. The first element of the stream
1575+-- is used as the initial value of the accumulator. Does nothing if the stream
1576+-- is empty.
9691577--
1578+-- @
1579+-- > S.toList $ S.scanl1 (+) $ fromList [1,2,3,4]
1580+-- [1,3,6,10]
1581+-- @
1582+--
1583+-- @since 0.6.0
9701584{-# INLINE scanl1' #-}
9711585scanl1' :: (IsStream t, Monad m) => (a -> a -> a) -> t m a -> t m a
9721586scanl1' step m = fromStreamD $ D.scanl1' step $ toStreamD m
@@ -997,10 +1611,19 @@ filterM p m = fromStreamD $ D.filterM p $ toStreamD m
9971611
9981612-- | Drop repeated elements that are adjacent to each other.
9991613--
1614+-- @since 0.6.0
10001615{-# INLINE uniq #-}
10011616uniq :: (Eq a, IsStream t, Monad m) => t m a -> t m a
10021617uniq = fromStreamD . D.uniq . toStreamD
10031618
1619+-- | Ensures that all the elements of the stream are identical and then returns
1620+-- that unique element.
1621+--
1622+-- @since 0.6.0
1623+{-# INLINE the #-}
1624+the :: (Eq a, Monad m) => SerialT m a -> m (Maybe a)
1625+the m = S.the (toStreamS m)
1626+
10041627-- | Take first 'n' elements from the stream and discard the rest.
10051628--
10061629-- @since 0.1.0
@@ -1049,10 +1672,18 @@ dropWhileM p m = fromStreamD $ D.dropWhileM p $ toStreamD m
10491672-- Transformation by Mapping
10501673------------------------------------------------------------------------------
10511674
1052−-- | Replace each element of the stream with the result of a monadic action
1053−-- applied on the element.
1675+-- |
1676+-- @
1677+-- mapM f = sequence . map f
1678+-- @
1679+--
1680+-- Apply a monadic function to each element of the stream and replace it with
1681+-- the output of the resulting action.
10541682--
10551683-- @
1684+-- > runStream $ S.mapM putStr $ S.fromList ["a", "b", "c"]
1685+-- abc
1686+--
10561687-- runStream $ S.replicateM 10 (return 1)
10571688-- & (serially . S.mapM (\\x -> threadDelay 1000000 >> print x))
10581689--
@@ -1072,10 +1703,18 @@ mapM = K.mapM
10721703mapMSerial :: Monad m => (a -> m b) -> SerialT m a -> SerialT m b
10731704mapMSerial = Serial.mapM
10741705
1075−-- | Reduce a stream of monadic actions to a stream of the output of those
1076−-- actions.
1706+-- |
1707+-- @
1708+-- sequence = mapM id
1709+-- @
1710+--
1711+-- Replace the elements of a stream of monadic actions with the outputs of
1712+-- those actions.
10771713--
10781714-- @
1715+-- > runStream $ S.sequence $ S.fromList [putStr "a", putStr "b", putStrLn "c"]
1716+-- abc
1717+--
10791718-- runStream $ S.replicateM 10 (return $ threadDelay 1000000 >> print 1)
10801719-- & (serially . S.sequence)
10811720--
@@ -1142,17 +1781,34 @@ reverse m = fromStream $ go K.nil (toStream m)
11421781-- Transformation by Inserting
11431782------------------------------------------------------------------------------
11441783
1145−-- | Generate a stream by performing the monadic action inbetween all elements
1146−-- of the given stream.
1784+-- | Generate a stream by performing a monadic action between consecutive
1785+-- elements of the given stream.
1786+--
1787+-- /Concurrent (do not use with 'parallely' on infinite streams)/
1788+--
1789+-- @
1790+-- > S.toList $ S.intersperseM (putChar \'a' >> return ',') $ S.fromList "hello"
1791+-- aaaa"h,e,l,l,o"
1792+-- @
11471793--
11481794-- @since 0.5.0
11491795{-# INLINE intersperseM #-}
11501796intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
11511797intersperseM = K.intersperseM
11521798
1153−-- | Inserts @x@ before the first element in the Stream that is
1154−-- less than @x@, based on the user supplied comparison function.
1799+-- | @insertBy cmp elem stream@ inserts @elem@ before the first element in
1800+-- @stream@ that is less than @elem@ when compared using @cmp@.
11551801--
1802+-- @
1803+-- insertBy cmp x = 'mergeBy' cmp ('yield' x)
1804+-- @
1805+--
1806+-- @
1807+-- > S.toList $ S.insertBy compare 2 $ S.fromList [1,3,5]
1808+-- [1,2,3,5]
1809+-- @
1810+--
1811+-- @since 0.6.0
11561812{-# INLINE insertBy #-}
11571813insertBy ::
11581814 (IsStream t, Monad m) => (a -> a -> Ordering) -> a -> t m a -> t m a
@@ -1162,9 +1818,15 @@ insertBy cmp x m = fromStreamS $ S.insertBy cmp x (toStreamS m)
11621818-- Deleting
11631819------------------------------------------------------------------------------
11641820
1165−-- | Deletes the first occurence of @x@ in the Stream that satisfies the
1166−-- equality predicate.
1821+-- | Deletes the first occurence of the element in the stream that satisfies
1822+-- the given equality predicate.
11671823--
1824+-- @
1825+-- > S.toList $ S.deleteBy (==) 3 $ S.fromList [1,3,3,5]
1826+-- [1,3,5]
1827+-- @
1828+--
1829+-- @since 0.6.0
11681830{-# INLINE deleteBy #-}
11691831deleteBy :: (IsStream t, Monad m) => (a -> a -> Bool) -> a -> t m a -> t m a
11701832deleteBy cmp x m = fromStreamS $ S.deleteBy cmp x (toStreamS m)
@@ -1173,20 +1835,38 @@ deleteBy cmp x m = fromStreamS $ S.deleteBy cmp x (toStreamS m)
11731835-- Zipping
11741836------------------------------------------------------------------------------
11751837
1176−-- | Pair each element in a stream with its index.
1838+-- |
1839+-- > indexed = S.zipWith (,) (S.intFrom 0)
1840+--
1841+-- Pair each element in a stream with its index.
1842+--
1843+-- @
1844+-- > S.toList $ S.indexed $ S.fromList "hello"
1845+-- [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
1846+-- @
11771847--
1848+-- @since 0.6.0
11781849{-# INLINE indexed #-}
11791850indexed :: (IsStream t, Monad m) => t m a -> t m (Int, a)
11801851indexed = fromStreamD . D.indexed . toStreamD
11811852
1182−-- | Pair each element in a stream with its index, starting from the
1853+-- |
1854+-- > indexedR n = S.zipWith (,) (S.intFromThen n (n - 1))
1855+--
1856+-- Pair each element in a stream with its index, starting from the
11831857-- given index @n@ and counting down.
11841858--
1859+-- @
1860+-- > S.toList $ S.indexedR 10 $ S.fromList "hello"
1861+-- [(9,'h'),(8,'e'),(7,'l'),(6,'l'),(5,'o')]
1862+-- @
1863+--
1864+-- @since 0.6.0
11851865{-# INLINE indexedR #-}
11861866indexedR :: (IsStream t, Monad m) => Int -> t m a -> t m (Int, a)
11871867indexedR n = fromStreamD . D.indexedR n . toStreamD
11881868
1189−-- | Zip two streams serially using a monadic zipping function.
1869+-- | Like 'zipWith' but using a monadic zipping function.
11901870--
11911871-- @since 0.4.0
11921872{-# INLINABLE zipWithM #-}
@@ -1195,6 +1875,11 @@ zipWithM f m1 m2 = fromStreamS $ S.zipWithM f (toStreamS m1) (toStreamS m2)
11951875
11961876-- | Zip two streams serially using a pure zipping function.
11971877--
1878+-- @
1879+-- > S.toList $ S.zipWith (+) (S.fromList [1,2,3]) (S.fromList [4,5,6])
1880+-- [5,7,9]
1881+-- @
1882+--
11981883-- @since 0.1.0
11991884{-# INLINABLE zipWith #-}
12001885zipWith :: (IsStream t, Monad m) => (a -> b -> c) -> t m a -> t m b -> t m c
@@ -1204,36 +1889,115 @@ zipWith f m1 m2 = fromStreamS $ S.zipWith f (toStreamS m1) (toStreamS m2)
12041889-- Comparison
12051890------------------------------------------------------------------------------
12061891
1207−-- | Compare two streams for equality using a equality function.
1892+-- | Compare two streams for equality using an equality function.
12081893--
1209−-- @since 0.5.3
1894+-- @since 0.6.0
12101895{-# INLINABLE eqBy #-}
1211−eqBy :: Monad m => (a -> b -> Bool) -> SerialT m a -> SerialT m b -> m Bool
1896+eqBy :: (IsStream t, Monad m) => (a -> b -> Bool) -> t m a -> t m b -> m Bool
12121897eqBy = P.eqBy
12131898
1214−-- | Compare two streams using a comparison function.
1899+-- | Compare two streams lexicographically using a comparison function.
12151900--
1216−-- @since 0.5.3
1901+-- @since 0.6.0
12171902{-# INLINABLE cmpBy #-}
12181903cmpBy
1219− :: Monad m
1220− => (a -> b -> Ordering) -> SerialT m a -> SerialT m b -> m Ordering
1904+ :: (IsStream t, Monad m)
1905+ => (a -> b -> Ordering) -> t m a -> t m b -> m Ordering
12211906cmpBy = P.cmpBy
12221907
1223−-- | Non-overloaded version of merge.
1908+------------------------------------------------------------------------------
1909+-- Merge
1910+------------------------------------------------------------------------------
1911+
1912+-- | Merge two streams using a comparison function. The head elements of both
1913+-- the streams are compared and the smaller of the two elements is emitted, if
1914+-- both elements are equal then the element from the first stream is used
1915+-- first.
1916+--
1917+-- If the streams are sorted in ascending order, the resulting stream would
1918+-- also remain sorted in ascending order.
1919+--
1920+-- @
1921+-- > S.toList $ S.mergeBy compare (S.fromList [1,3,5]) (S.fromList [2,4,6,8])
1922+-- [1,2,3,4,5,6,8]
1923+-- @
1924+--
1925+-- @since 0.6.0
12241926{-# INLINABLE mergeBy #-}
12251927mergeBy ::
12261928 (IsStream t, Monad m) => (a -> a -> Ordering) -> t m a -> t m a -> t m a
12271929mergeBy f m1 m2 = fromStreamS $ S.mergeBy f (toStreamS m1) (toStreamS m2)
12281930
1229−-- | Merge two sorted streams.
1931+-- | Like 'mergeBy' but with a monadic comparison function.
1932+--
1933+-- Merge two streams randomly:
1934+--
1935+-- @
1936+-- > randomly _ _ = randomIO >>= \x -> return $ if x then LT else GT
1937+-- > S.toList $ S.mergeByM randomly (S.fromList [1,1,1,1]) (S.fromList [2,2,2,2])
1938+-- [2,1,2,2,2,1,1,1]
1939+-- @
1940+--
1941+-- Merge two streams in a proportion of 2:1:
1942+--
1943+-- @
1944+-- proportionately m n = do
1945+-- ref <- newIORef $ cycle $ concat [replicate m LT, replicate n GT]
1946+-- return $ \\_ _ -> do
1947+-- r <- readIORef ref
1948+-- writeIORef ref $ tail r
1949+-- return $ head r
1950+--
1951+-- main = do
1952+-- f <- proportionately 2 1
1953+-- xs <- S.toList $ S.mergeByM f (S.fromList [1,1,1,1,1,1]) (S.fromList [2,2,2])
1954+-- print xs
1955+-- @
1956+-- @
1957+-- [1,1,2,1,1,2,1,1,2]
1958+-- @
1959+--
1960+-- @since 0.6.0
1961+{-# INLINABLE mergeByM #-}
1962+mergeByM
1963+ :: (IsStream t, Monad m)
1964+ => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
1965+mergeByM f m1 m2 = fromStreamS $ S.mergeByM f (toStreamS m1) (toStreamS m2)
1966+
1967+-- Holding this back for now, we may want to use the name "merge" differently
1968+{-
1969+-- | Same as @'mergeBy' 'compare'@.
1970+--
1971+-- @
1972+-- > S.toList $ S.merge (S.fromList [1,3,5]) (S.fromList [2,4,6,8])
1973+-- [1,2,3,4,5,6,8]
1974+-- @
1975+--
1976+-- @since 0.6.0
12301977{-# INLINABLE merge #-}
12311978merge ::
12321979 (IsStream t, Monad m, Ord a) => t m a -> t m a -> t m a
12331980merge = mergeBy compare
1234−
1235−-- | Ensures all the elements are identical and then returns
1236−-- that unique element.
1237−{-# INLINE the #-}
1238−the :: (Eq a, Monad m) => SerialT m a -> m (Maybe a)
1239−the m = S.the (toStreamS m)
1981+-}
1982+
1983+-- | Like 'mergeBy' but merges concurrently (i.e. both the elements being
1984+-- merged are generated concurrently).
1985+--
1986+-- @since 0.6.0
1987+mergeAsyncBy :: (IsStream t, MonadAsync m)
1988+ => (a -> a -> Ordering) -> t m a -> t m a -> t m a
1989+mergeAsyncBy f m1 m2 = K.fromStream $ K.Stream $ \st stp sng yld -> do
1990+ ma <- mkAsync' (rstState st) m1
1991+ mb <- mkAsync' (rstState st) m2
1992+ K.unStream (K.toStream (K.mergeBy f ma mb)) (rstState st) stp sng yld
1993+
1994+-- | Like 'mergeByM' but merges concurrently (i.e. both the elements being
1995+-- merged are generated concurrently).
1996+--
1997+-- @since 0.6.0
1998+mergeAsyncByM :: (IsStream t, MonadAsync m)
1999+ => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
2000+mergeAsyncByM f m1 m2 = K.fromStream $ K.Stream $ \st stp sng yld -> do
2001+ ma <- mkAsync' (rstState st) m1
2002+ mb <- mkAsync' (rstState st) m2
2003+ K.unStream (K.toStream (K.mergeByM f ma mb)) (rstState st) stp sng yld