@@ -0,0 +1,625 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE RankNTypes #-}
3+{-# LANGUAGE FlexibleContexts #-}
4+
5+#if __GLASGOW_HASKELL__ >= 800
6+{-# OPTIONS_GHC -Wno-orphans #-}
7+#endif
8+
9+#include "Streams/inline.hs"
10+
11+-- |
12+-- Module : Streamly.Prelude
13+-- Copyright : (c) 2017 Harendra Kumar
14+--
15+-- License : BSD3
16+-- Maintainer : harendra.kumar@gmail.com
17+-- Stability : experimental
18+-- Portability : GHC
19+--
20+-- This module is designed to be imported qualified:
21+--
22+-- @
23+-- import qualified Streamly.Prelude as S
24+-- @
25+--
26+-- Functions with the suffix @M@ are general functions that work on monadic
27+-- arguments. The corresponding functions without the suffix @M@ work on pure
28+-- arguments and can in general be derived from their monadic versions but are
29+-- provided for convenience and for consistency with other pure APIs in the
30+-- @base@ package.
31+--
32+-- In many cases, short definitions of the combinators are provided in the
33+-- documentation for illustration. The actual implementation may differ for
34+-- performance reasons.
35+--
36+-- Functions having a 'MonadAsync' constraint work concurrently when used with
37+-- appropriate stream type combinator. Please be careful to not use 'parallely'
38+-- with infinite streams.
39+--
40+-- Deconstruction and folds accept a 'SerialT' type instead of a polymorphic
41+-- type to ensure that streams always have a concrete monomorphic type by
42+-- default, reducing type errors. In case you want to use any other type of
43+-- stream you can use one of the type combinators provided in the "Streamly"
44+-- module to convert the stream type.
45+
46+module Streamly.Prelude
47+ (
48+ -- * Construction
49+ -- ** Primitives
50+ -- | Primitives to construct a stream from pure values or monadic actions.
51+ -- All other stream construction and generation combinators described later
52+ -- can be expressed in terms of these primitives. However, the special
53+ -- versions provided in this module can be much more efficient in most
54+ -- cases. Users can create custom combinators using these primitives.
55+
56+ nil
57+ , cons
58+ , (.:)
59+
60+ , consM
61+ , (|:)
62+
63+ -- ** From Values
64+ -- | Generate a monadic stream from a seed value or values.
65+ , yield
66+ , yieldM
67+ , repeat
68+ , repeatM
69+ , replicate
70+ , replicateM
71+
72+ -- Note: Using enumeration functions e.g. 'Prelude.enumFromThen' turns out
73+ -- to be slightly faster than the idioms like @[from, then..]@.
74+ --
75+ -- ** Enumeration
76+ -- | We can use the 'Enum' type class to enumerate a 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.
84+ -- The 'Enumerable' type class provides corresponding functions that
85+ -- generate a stream instead of a list, efficiently.
86+
87+ , Enumerable (..)
88+ , enumerate
89+ , enumerateTo
90+
91+ -- ** From Generators
92+ -- | Generate a monadic stream from a seed value and a generator function.
93+ , unfoldr
94+ , unfoldrM
95+ , iterate
96+ , iterateM
97+ , fromIndices
98+ , fromIndicesM
99+
100+ -- ** From Containers
101+ -- | Convert an input structure, container or source into a stream. All of
102+ -- these can be expressed in terms of primitives.
103+ , fromList
104+ , fromListM
105+ , fromFoldable
106+ , fromFoldableM
107+
108+ -- * Elimination
109+
110+ -- ** Deconstruction
111+ -- | It is easy to express all the folds in terms of the 'uncons' primitive,
112+ -- however the specific implementations provided later are generally more
113+ -- efficient.
114+ --
115+ , uncons
116+ , tail
117+ , init
118+
119+ -- ** Folding
120+-- | In imperative terms a fold can be considered as a loop over the stream
121+-- that reduces the stream to a single value.
122+-- Left and right folds use a fold function @f@ and an identity element @z@
123+-- (@zero@) to recursively deconstruct a structure and then combine and reduce
124+-- the values or transform and reconstruct a new container.
125+--
126+-- In general, a right fold is suitable for transforming and reconstructing a
127+-- right associated structure (e.g. cons lists and streamly streams) and a left
128+-- fold is suitable for reducing a right associated structure. The behavior of
129+-- right and left folds are described in detail in the individual fold's
130+-- documentation. To illustrate the two folds for cons lists:
131+--
132+-- > foldr :: (a -> b -> b) -> b -> [a] -> b
133+-- > foldr f z [] = z
134+-- > foldr f z (x:xs) = x `f` foldr f z xs
135+-- >
136+-- > foldl :: (b -> a -> b) -> b -> [a] -> b
137+-- > foldl f z [] = z
138+-- > foldl f z (x:xs) = foldl f (z `f` x) xs
139+--
140+-- @foldr@ is conceptually equivalent to:
141+--
142+-- > foldr f z [] = z
143+-- > foldr f z [x] = f x z
144+-- > foldr f z xs = foldr f (foldr f z (tail xs)) [head xs]
145+--
146+-- @foldl@ is conceptually equivalent to:
147+--
148+-- > foldl f z [] = z
149+-- > foldl f z [x] = f z x
150+-- > foldl f z xs = foldl f (foldl f z (init xs)) [last xs]
151+--
152+-- Left and right folds are duals of each other.
153+--
154+-- @
155+-- foldr f z xs = foldl (flip f) z (reverse xs)
156+-- foldl f z xs = foldr (flip f) z (reverse xs)
157+-- @
158+--
159+-- More generally:
160+--
161+-- @
162+-- foldr f z xs = foldl g id xs z where g k x = k . f x
163+-- foldl f z xs = foldr g id xs z where g x k = k . flip f x
164+-- @
165+--
166+
167+-- As a general rule, foldr cannot have state and foldl cannot have control.
168+
169+-- NOTE: Folds are inherently serial as each step needs to use the result of
170+-- the previous step. However, it is possible to fold parts of the stream in
171+-- parallel and then combine the results using a monoid.
172+
173+ -- ** Right Folds
174+ , foldrM
175+ , foldrS
176+ , foldrT
177+ , foldr
178+
179+ -- ** Left Folds
180+ , foldl'
181+ , foldl1'
182+ , foldlM'
183+
184+ -- ** Composable Left Folds
185+ -- $runningfolds
186+
187+ , runFold
188+
189+ -- ** Full Folds
190+ -- | Folds that are guaranteed to evaluate the whole stream.
191+
192+ -- -- ** To Summary (Full Folds)
193+ -- -- | Folds that summarize the stream to a single value.
194+ , drain
195+ , last
196+ , length
197+ , sum
198+ , product
199+ --, mconcat
200+
201+ -- -- ** To Summary (Maybe) (Full Folds)
202+ -- -- | Folds that summarize a non-empty stream to a 'Just' value and return
203+ -- 'Nothing' for an empty stream.
204+ , maximumBy
205+ , maximum
206+ , minimumBy
207+ , minimum
208+ , the
209+ -- , toListRev -- experimental
210+
211+ -- ** Lazy Folds
212+ --
213+ -- | Folds that generate a lazy structure. Note that the generated
214+ -- structure may not be lazy if the underlying monad is strict.
215+
216+ -- -- ** To Containers (Full Folds)
217+ -- -- | Convert or divert a stream into an output structure, container or
218+ -- sink.
219+ , toList
220+
221+ -- ** Partial Folds
222+ -- | Folds that may terminate before evaluating the whole stream. These
223+ -- folds strictly evaluate the stream until the result is determined.
224+
225+ -- -- ** To Elements (Partial Folds)
226+ , drainN
227+ , drainWhile
228+
229+ -- -- | Folds that extract selected elements of a stream or their properties.
230+ , (!!)
231+ , head
232+ , findM
233+ , find
234+ , lookup
235+ , findIndex
236+ , elemIndex
237+
238+ -- -- ** To Boolean (Partial Folds)
239+ -- -- | Folds that summarize the stream to a boolean value.
240+ , null
241+ , elem
242+ , notElem
243+ , all
244+ , any
245+ , and
246+ , or
247+
248+ -- * Transformation
249+
250+ --, transform
251+
252+ -- ** Mapping
253+ -- | In imperative terms a map operation can be considered as a loop over
254+ -- the stream that transforms the stream into another stream by performing
255+ -- an operation on each element of the stream.
256+ --
257+ -- 'map' is the least powerful transformation operation with strictest
258+ -- guarantees. A map, (1) is a stateless loop which means that no state is
259+ -- allowed to be carried from one iteration to another, therefore,
260+ -- operations on different elements are guaranteed to not affect each
261+ -- other, (2) is a strictly one-to-one transformation of stream elements
262+ -- which means it guarantees that no elements can be added or removed from
263+ -- the stream, it can merely transform them.
264+ , map
265+ , sequence
266+ , mapM
267+ , mapM_
268+
269+ -- ** Scanning
270+ --
271+ -- | A scan is more powerful than map. While a 'map' is a stateless loop, a
272+ -- @scan@ is a stateful loop which means that a state can be shared across
273+ -- all the loop iterations, therefore, future iterations can be impacted by
274+ -- the state changes made by the past iterations. A scan yields the state
275+ -- of the loop after each iteration. Like a map, a @postscan@ or @prescan@
276+ -- does not add or remove elements in the stream, it just transforms them.
277+ -- However, a @scan@ adds one extra element to the stream.
278+ --
279+ -- A left associative scan, also known as a prefix sum, can be thought of
280+ -- as a stream transformation consisting of left folds of all prefixes of a
281+ -- stream. Another way of thinking about it is that it streams all the
282+ -- intermediate values of the accumulator while applying a left fold on the
283+ -- input stream. A right associative scan, on the other hand, can be
284+ -- thought of as a stream consisting of right folds of all the suffixes of
285+ -- a stream.
286+ --
287+ -- The following equations hold for lists:
288+ --
289+ -- > scanl f z xs == map (foldl f z) $ inits xs
290+ -- > scanr f z xs == map (foldr f z) $ tails xs
291+ --
292+ -- @
293+ -- > scanl (+) 0 [1,2,3,4]
294+ -- 0 = 0
295+ -- 0 + 1 = 1
296+ -- 0 + 1 + 2 = 3
297+ -- 0 + 1 + 2 + 3 = 6
298+ -- 0 + 1 + 2 + 3 + 4 = 10
299+ --
300+ -- > scanr (+) 0 [1,2,3,4]
301+ -- 1 + 2 + 3 + 4 + 0 = 10
302+ -- 2 + 3 + 4 + 0 = 9
303+ -- 3 + 4 + 0 = 7
304+ -- 4 + 0 = 4
305+ -- 0 = 0
306+ -- @
307+ --
308+ -- Left and right scans are duals:
309+ --
310+ -- > scanr f z xs == reverse $ scanl (flip f) z (reverse xs)
311+ -- > scanl f z xs == reverse $ scanr (flip f) z (reverse xs)
312+ --
313+ -- A scan is a stateful map i.e. a combination of map and fold:
314+ --
315+ -- > map f xs = tail $ scanl (\_ x -> f x) z xs
316+ -- > map f xs = reverse $ head $ scanr (\_ x -> f x) z xs
317+ --
318+ -- > foldl f z xs = last $ scanl f z xs
319+ -- > foldr f z xs = head $ scanr f z xs
320+
321+ -- ** Left scans
322+ , scanl'
323+ , scanlM'
324+ , postscanl'
325+ , postscanlM'
326+ -- , prescanl'
327+ -- , prescanlM'
328+ , scanl1'
329+ , scanl1M'
330+
331+ -- ** Scan Using Fold
332+ , runScan
333+ , runPostscan
334+
335+ -- , lscanl'
336+ -- , lscanlM'
337+ -- , lscanl1'
338+ -- , lscanl1M'
339+ --
340+ -- , lpostscanl'
341+ -- , lpostscanlM'
342+ -- , lprescanl'
343+ -- , lprescanlM'
344+
345+ -- ** Indexing
346+ , indexed
347+ , indexedR
348+ -- , timestamped
349+ -- , timestampedR -- timer
350+
351+ -- ** Filtering
352+ -- | Remove some elements from the stream based on a predicate. In
353+ -- imperative terms a filter over a stream corresponds to a loop with a
354+ -- @continue@ clause for the cases when the predicate fails.
355+
356+ , filter
357+ , filterM
358+
359+ -- ** Stateful Filters
360+ , take
361+ -- , takeEnd
362+ , takeWhile
363+ , takeWhileM
364+ -- , takeWhileEnd
365+ , drop
366+ -- , dropEnd
367+ , dropWhile
368+ , dropWhileM
369+ -- , dropWhileEnd
370+ -- , dropAround
371+ , deleteBy
372+ , uniq
373+ -- , uniqBy -- by predicate e.g. to remove duplicate "/" in a path
374+ -- , uniqOn -- to remove duplicate sequences
375+ -- , pruneBy -- dropAround + uniqBy - like words
376+
377+ -- ** Mapping Filters
378+ -- | Mapping along with filtering
379+
380+ , mapMaybe
381+ , mapMaybeM
382+
383+ -- ** Scanning Filters
384+ -- | Stateful transformation along with filtering
385+
386+ , findIndices
387+ , elemIndices
388+ -- , seqIndices -- search a sequence in the stream
389+
390+ -- ** Insertion
391+ -- | Insertion adds more elements to the stream.
392+
393+ , insertBy
394+ , intersperseM
395+ , intersperse
396+ -- , insertAfterEach
397+ -- , intersperseBySpan
398+ -- , intersperseByTime
399+
400+ -- ** Reordering
401+ , reverse
402+ -- , reverse'
403+
404+ -- * Multi-Stream Operations
405+ -- | New streams can be constructed by appending, merging or zipping
406+ -- existing streams.
407+
408+ -- ** Appending
409+ -- | Streams form a 'Semigroup' and a 'Monoid' under the append
410+ -- operation.
411+ --
412+ -- @
413+ --
414+ -- -------Stream m a------|-------Stream m a------|=>----Stream m a---
415+ --
416+ -- @
417+ --
418+ -- @
419+ -- >> S.toList $ S.fromList [1,2] \<> S.fromList [3,4]
420+ -- [1,2,3,4]
421+ -- >> S.toList $ fold $ [S.fromList [1,2], S.fromList [3,4]]
422+ -- [1,2,3,4]
423+ -- @
424+
425+ -- ** Merging
426+ -- | Streams form a commutative semigroup under the merge
427+ -- operation.
428+ --
429+ -- @
430+ --
431+ -- -------Stream m a------|
432+ -- |=>----Stream m a---
433+ -- -------Stream m a------|
434+ -- @
435+ --
436+
437+ -- , merge
438+ , mergeBy
439+ , mergeByM
440+ , mergeAsyncBy
441+ , mergeAsyncByM
442+
443+ -- ** Zipping
444+ -- |
445+ -- @
446+ --
447+ -- -------Stream m a------|
448+ -- |=>----Stream m c---
449+ -- -------Stream m b------|
450+ -- @
451+ --
452+ , zipWith
453+ , zipWithM
454+ , zipAsyncWith
455+ , zipAsyncWithM
456+
457+ -- ** Nested Streams
458+ -- | Stream operations represent loops in imperative programming, streams
459+ -- of streams represent nested loops.
460+
461+ , concatMapM
462+ , concatMap
463+ , concatMapBy
464+ -- , interposeBy
465+ -- , intercalate
466+
467+ -- -- ** Breaking
468+
469+ -- By chunks
470+ -- , splitAt -- spanN
471+ -- , splitIn -- sessionN
472+
473+ -- By elements
474+ -- , span -- spanWhile
475+ -- , break -- breakBefore
476+ -- , breakAfter
477+ -- , breakOn
478+ -- , breakAround
479+ -- , spanBy
480+ -- , spanByRolling
481+
482+ -- By sequences
483+ -- breakOnSeq
484+
485+ -- ** Splitting
486+ -- | Streams can be split into segments in space or in time. We use the
487+ -- term @chunk@ to refer to a spatial length of the stream (spatial window)
488+ -- and the term @session@ to refer to a length in time (time window).
489+
490+ -- In imperative terms, grouped folding can be considered as a nested loop
491+ -- where we loop over the stream to group elements and then loop over
492+ -- individual groups to fold them to a single value that is yielded in the
493+ -- output stream.
494+
495+ -- , groupScan
496+
497+ -- -- *** Chunks
498+ , chunksOf
499+ , sessionsOf
500+
501+ -- , lchunksOf
502+ -- , lsessionsOf
503+
504+ -- -- *** Using Element Separators
505+ -- On == Dropping the separator
506+ , splitOn
507+ , splitOnSuffix
508+ -- , splitOnPrefix
509+
510+ -- By == Keeping the separator
511+ -- , splitBy
512+ , splitBySuffix
513+ -- , splitByPrefix
514+ , wordsBy -- stripAndCompactBy
515+
516+ -- -- *** Using Sequence Separators
517+ -- , splitOnSeq
518+ -- , splitOnSuffixSeq
519+ -- , splitOnPrefixSeq
520+
521+ -- Keeping the delimiters
522+ -- , splitBySeq
523+ -- , splitBySeqSuffix
524+ -- , splitBySeqPrefix
525+ -- , wordsBySeq
526+
527+ -- Splitting using multiple sequence separators
528+ -- , splitOnAnySeq
529+ -- , splitOnAnySuffixSeq
530+ -- , splitOnAnyPrefixSeq
531+
532+ -- ** Grouping
533+ , groups
534+ , groupsBy
535+ , groupsByRolling
536+
537+ -- ** Distributing
538+ , trace
539+ , tap
540+
541+ {-
542+ -- * Windowed Classification
543+ -- | Split the stream into windows or chunks in space or time. Each window
544+ -- can be associated with a key, all events associated with a particular
545+ -- key in the window can be folded to a single result. The stream is split
546+ -- into windows of specified size, the window can be terminated early if
547+ -- the closing flag is specified in the input stream.
548+ --
549+ -- The term "chunk" is used for a space window and the term "session" is
550+ -- used for a time window.
551+
552+ -- ** Tumbling Windows
553+ -- | A new window starts after the previous window is finished.
554+ -- , classifyChunksOf
555+ -- , classifySessionsOf
556+
557+ -- ** Keep Alive Windows
558+ -- | The window size is extended if an event arrives within the specified
559+ -- window size. This can represent sessions with idle or inactive timeout.
560+ -- , classifyKeepAliveChunks
561+ -- , classifyKeepAliveSessions
562+
563+ {-
564+ -- ** Sliding Windows
565+ -- | A new window starts after the specified slide from the previous
566+ -- window. Therefore windows can overlap.
567+ , classifySlidingChunks
568+ , classifySlidingSessions
569+ -}
570+ -- ** Sliding Window Buffers
571+ -- , slidingChunkBuffer
572+ -- , slidingSessionBuffer
573+ -}
574+
575+ -- ** Containers of Streams
576+ -- | These are variants of standard 'Foldable' fold functions that use a
577+ -- polymorphic stream sum operation (e.g. 'async' or 'wSerial') to fold a
578+ -- finite container of streams.
579+ --
580+ , foldWith
581+ , foldMapWith
582+ , forEachWith
583+
584+ -- ** Folding
585+ , eqBy
586+ , cmpBy
587+ , isPrefixOf
588+ -- , isSuffixOf
589+ -- , isInfixOf
590+ , isSubsequenceOf
591+ , stripPrefix
592+ -- , stripSuffix
593+ -- , stripInfix
594+
595+ -- * Exceptions
596+ , before
597+ , after
598+ , bracket
599+ , onException
600+ , finally
601+ , handle
602+
603+ -- * Deprecated
604+ , once
605+ , each
606+ , scanx
607+ , foldx
608+ , foldxM
609+ , foldr1
610+ , runStream
611+ , runN
612+ , runWhile
613+ , fromHandle
614+ , toHandle
615+ )
616+where
617+
618+import Prelude
619+ hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
620+ foldl, map, mapM, mapM_, sequence, all, any, sum, product, elem,
621+ notElem, maximum, minimum, head, last, tail, length, null,
622+ reverse, iterate, init, and, or, lookup, foldr1, (!!),
623+ scanl, scanl1, repeat, replicate, concatMap, span)
624+
625+import Streamly.Prelude.Internal