on master help sign in
Fix examples in code to work with doctest.
commitda906ce49d45d2b27c0d18fd0dc276e650419dfa authorPranay Sashank <pranaysashank@composewell.com> dateThu 4 Feb 2021, 23:57 (6 years ago) parentc88b23e
20 files changed+583−397
src/Streamly/Data/Fold.hs+13−6 src/Streamly/Internal/Data/Array/Foreign/Types.hs+15−8 src/Streamly/Internal/Data/Fold.hs+56−44 src/Streamly/Internal/Data/Fold/Types.hs+14−3 src/Streamly/Internal/Data/Parser.hs+78−52 src/Streamly/Internal/Data/Parser/ParserD.hs+20−8 src/Streamly/Internal/Data/Parser/ParserD/Types.hs+10−1 src/Streamly/Internal/Data/Stream/IsStream/Common.hs+40−35 src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+9−2 src/Streamly/Internal/Data/Stream/IsStream/Generate.hs+25−16 src/Streamly/Internal/Data/Stream/IsStream/Nesting.hs+142−102 src/Streamly/Internal/Data/Stream/IsStream/Top.hs+12−8 src/Streamly/Internal/Data/Stream/IsStream/Transform.hs+56−68 src/Streamly/Internal/Data/Stream/Parallel.hs+28−13 src/Streamly/Internal/Data/Stream/StreamK.hs+4 src/Streamly/Internal/Data/Unfold/Types.hs+6 src/Streamly/Internal/Unicode/Array/Char.hs+12−5 src/Streamly/Internal/Unicode/Array/Prim/Pinned.hs+12−6 src/Streamly/Internal/Unicode/Stream.hs+11−4 src/Streamly/Prelude.hs+20−16
src/Streamly/Data/Fold.hs+13−6
@@ -62,7 +62,7 @@ module Streamly.Data.Fold
6262 -- A 'Fold' can be run over a stream using the 'Streamly.Prelude.fold'
6363 -- combinator:
6464 --
65− -- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
65+ -- >>> Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
6666 -- 5050
6767
6868 Fold -- (..)
@@ -123,7 +123,7 @@ module Streamly.Data.Fold
123123 -- Transformations can be applied either on the input side or on the output
124124 -- side. The 'Functor' instance of a fold maps on the output of the fold:
125125 --
126− -- >>> S.fold (fmap show FL.sum) (S.enumerateFromTo 1 100)
126+ -- >>> Stream.fold (fmap show Fold.sum) (Stream.enumerateFromTo 1 100)
127127 -- "5050"
128128 --
129129 -- Note: Output transformations are also known as covariant
@@ -199,16 +199,16 @@ module Streamly.Data.Fold
199199 -- To compute the average of numbers in a stream without going through the
200200 -- stream twice:
201201 --
202− -- >>> let avg = (/) <$> FL.sum <*> fmap fromIntegral FL.length
203− -- >>> S.fold avg (S.enumerateFromTo 1.0 100.0)
202+ -- >>> let avg = (/) <$> Fold.sum <*> fmap fromIntegral Fold.length
203+ -- >>> Stream.fold avg (Stream.enumerateFromTo 1.0 100.0)
204204 -- 50.5
205205 --
206206 -- The 'Semigroup' and 'Monoid' instances of a distributing fold distribute
207207 -- the input to both the folds and combines the outputs using Monoid or
208208 -- Semigroup instances of the output types:
209209 --
210− -- >>> import Data.Monoid (Sum)
211− -- >>> S.fold (FL.head <> FL.last) (fmap Sum $ S.enumerateFromTo 1.0 100.0)
210+ -- >>> import Data.Monoid (Sum(..))
211+ -- >>> Stream.fold (Fold.head <> Fold.last) (fmap Sum $ Stream.enumerateFromTo 1.0 100.0)
212212 -- Just (Sum {getSum = 101.0})
213213 --
214214 -- The 'Num', 'Floating', and 'Fractional' instances work in the same way.
@@ -265,3 +265,10 @@ import Prelude
265265 span, splitAt, break, mapM)
266266
267267import Streamly.Internal.Data.Fold
268+
269+--
270+-- $setup
271+-- >>> :m
272+-- >>> import Prelude hiding (head, sum, last, length)
273+-- >>> import qualified Streamly.Prelude as Stream
274+-- >>> import qualified Streamly.Data.Fold as Fold
src/Streamly/Internal/Data/Array/Foreign/Types.hs+15−8
@@ -117,6 +117,12 @@ import Data.Semigroup (Semigroup(..))
117117import qualified Data.Foldable as F
118118#endif
119119
120+--
121+-- $setup
122+-- >>> :m
123+-- >>> import Prelude hiding (length, foldr, read, unlines, splitAt)
124+-- >>> import Streamly.Internal.Data.Array.Foreign as Array
125+
120126-------------------------------------------------------------------------------
121127-- Array Data Type
122128-------------------------------------------------------------------------------
@@ -230,11 +236,12 @@ fromPtr n ptr = MA.unsafeInlineIO $ do
230236-- characters that can be encoded in a byte i.e. characters or literal bytes in
231237-- the range from 0-255.
232238--
233−-- >>> fromAddr# 5 "hello world!"#
234−-- > [104,101,108,108,111]
239+-- >>> import Data.Word (Word8)
240+-- >>> Array.fromAddr# 5 "hello world!"# :: Array Word8
241+-- [104,101,108,108,111]
235242--
236−-- >>> fromAddr# 3 "\255\NUL\255"#
237−-- > [255,0,255]
243+-- >>> Array.fromAddr# 3 "\255\NUL\255"# :: Array Word8
244+-- [255,0,255]
238245--
239246-- /See also: 'fromString#'/
240247--
@@ -262,11 +269,11 @@ fromAddr# n addr# = fromPtr n (castPtr $ Ptr addr#)
262269-- of bytes terminated by a NUL byte (a 'CString') corresponding to the
263270-- given unicode string.
264271--
265−-- >>> fromCString# "hello world!"#
266−-- > [104,101,108,108,111,32,119,111,114,108,100,33]
272+-- >>> Array.fromCString# "hello world!"#
273+-- [104,101,108,108,111,32,119,111,114,108,100,33]
267274--
268−-- >>> fromCString# "\255\NUL\255"#
269−-- > [255]
275+-- >>> Array.fromCString# "\255\NUL\255"#
276+-- [255]
270277--
271278-- /See also: 'fromAddr#'/
272279--
src/Streamly/Internal/Data/Fold.hs+56−44
@@ -254,6 +254,15 @@ import Prelude hiding
254254 , span, splitAt, break, mapM, zip)
255255import Streamly.Internal.Data.Fold.Types
256256
257+-- $setup
258+-- >>> :m
259+-- >>> import Prelude hiding (break, map, span, splitAt)
260+-- >>> import qualified Streamly.Prelude as Stream
261+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, foldMany)
262+-- >>> import qualified Streamly.Data.Fold as Fold
263+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
264+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
265+
257266------------------------------------------------------------------------------
258267-- hoist
259268------------------------------------------------------------------------------
@@ -327,7 +336,7 @@ mapM = rmapM
327336-- >>> f x = if even x then Just x else Nothing
328337-- >>> fld = Fold.mapMaybe f Fold.toList
329338-- >>> Stream.fold fld (Stream.enumerateFromTo 1 10)
330−-- [2,4,6,8]
339+-- [2,4,6,8,10]
331340--
332341-- /Internal/
333342{-# INLINE mapMaybe #-}
@@ -847,7 +856,7 @@ null = mkFold (\() _ -> Done False) (Partial ()) (const True)
847856-- | Returns 'True' if any of the elements of a stream satisfies a predicate.
848857--
849858-- >>> Stream.fold (Fold.any (== 0)) $ Stream.fromList [1,0,1]
850−-- > True
859+-- True
851860--
852861-- @since 0.7.0
853862{-# INLINE any #-}
@@ -879,7 +888,7 @@ elem a = any (a ==)
879888-- | Returns 'True' if all elements of a stream satisfy a predicate.
880889--
881890-- >>> Stream.fold (Fold.all (== 0)) $ Stream.fromList [1,0,1]
882−-- > False
891+-- False
883892--
884893-- @since 0.7.0
885894{-# INLINABLE all #-}
@@ -942,25 +951,25 @@ or = any (== True)
942951-- elements of its input are consumed by fold @f1@ and the rest of the stream
943952-- is consumed by fold @f2@.
944953--
945−-- > let splitAt_ n xs = S.fold (FL.splitAt n FL.toList FL.toList) $ S.fromList xs
954+-- >>> let splitAt_ n xs = Stream.fold (Fold.splitAt n Fold.toList Fold.toList) $ Stream.fromList xs
946955--
947956-- >>> splitAt_ 6 "Hello World!"
948−-- > ("Hello ","World!")
957+-- ("Hello ","World!")
949958--
950959-- >>> splitAt_ (-1) [1,2,3]
951−-- > ([],[1,2,3])
960+-- ([],[1,2,3])
952961--
953962-- >>> splitAt_ 0 [1,2,3]
954−-- > ([],[1,2,3])
963+-- ([],[1,2,3])
955964--
956965-- >>> splitAt_ 1 [1,2,3]
957−-- > ([1],[2,3])
966+-- ([1],[2,3])
958967--
959968-- >>> splitAt_ 3 [1,2,3]
960−-- > ([1,2,3],[])
969+-- ([1,2,3],[])
961970--
962971-- >>> splitAt_ 4 [1,2,3]
963−-- > ([1,2,3],[])
972+-- ([1,2,3],[])
964973--
965974-- > splitAt n f1 f2 = splitWith (,) (takeLE n f1) f2
966975--
@@ -1009,9 +1018,9 @@ splitAt n fld = splitWith (,) (takeLE n fld)
10091018--
10101019-- Let's use the following definition for illustration:
10111020--
1012−-- > splitOn p = Stream.foldMany (Fold.sliceSepBy pred Fold.toList)
1013−-- > splitOn' p = Stream.toList . splitOn p . Stream.fromList
1014−--
1021+-- >>> splitOn p = Stream.foldMany (Fold.sliceSepBy pred Fold.toList)
1022+-- >>> splitOn' p = Stream.toList . splitOn p . Stream.fromList
1023+
10151024-- >>> splitOn' (== '.') ""
10161025-- [""]
10171026--
@@ -1019,16 +1028,16 @@ splitAt n fld = splitWith (,) (takeLE n fld)
10191028-- ["",""]
10201029--
10211030-- >>> splitOn' (== '.') ".a"
1022−-- > ["","a"]
1031+-- ["","a"]
10231032--
10241033-- >>> splitOn' (== '.') "a."
1025−-- > ["a",""]
1034+-- ["a",""]
10261035--
10271036-- >>> splitOn' (== '.') "a.b"
1028−-- > ["a","b"]
1037+-- ["a","b"]
10291038--
10301039-- >>> splitOn' (== '.') "a..b"
1031−-- > ["a","","b"]
1040+-- ["a","","b"]
10321041--
10331042-- Stops - when the predicate succeeds.
10341043--
@@ -1102,7 +1111,7 @@ breakOn pat f m = undefined
11021111-- ---stream m a---| |---m (b,c)
11031112-- |-------Fold m a c--------|
11041113-- @
1105−-- >>> S.fold (FL.tee FL.sum FL.length) (S.enumerateFromTo 1.0 100.0)
1114+-- >>> Stream.fold (Fold.tee Fold.sum Fold.length) (Stream.enumerateFromTo 1.0 100.0)
11061115-- (5050.0,100)
11071116--
11081117-- @since 0.7.0
@@ -1126,7 +1135,7 @@ tee = teeWith (,)
11261135-- ...
11271136-- @
11281137--
1129−-- >>> S.fold (FL.distribute [FL.sum, FL.length]) (S.enumerateFromTo 1 5)
1138+-- >>> Stream.fold (Fold.distribute [Fold.sum, Fold.length]) (Stream.enumerateFromTo 1 5)
11301139-- [15,5]
11311140--
11321141-- This is the consumer side dual of the producer side 'sequence' operation.
@@ -1154,10 +1163,12 @@ distribute = foldr (teeWith (:)) (yield [])
11541163--
11551164-- Send input to either fold randomly:
11561165--
1157−-- >>> import System.Random (randomIO)
1158−-- >>> randomly a = randomIO >>= \x -> return $ if x then Left a else Right a
1159−-- >>> S.fold (FL.partitionByM randomly FL.length FL.length) (S.enumerateFromTo 1 100)
1166+-- @
1167+-- > import System.Random (randomIO)
1168+-- > randomly a = randomIO >>= \\x -> return $ if x then Left a else Right a
1169+-- > Stream.fold (Fold.partitionByM randomly Fold.length Fold.length) (Stream.enumerateFromTo 1 100)
11601170-- (59,41)
1171+-- @
11611172--
11621173-- Send input to the two folds in a proportion of 2:1:
11631174--
@@ -1279,13 +1290,13 @@ partitionByMinM = undefined
12791290--
12801291-- Count even and odd numbers in a stream:
12811292--
1282−-- @
1283−-- >>> let f = FL.partitionBy (\\n -> if even n then Left n else Right n)
1284−-- (fmap (("Even " ++) . show) FL.length)
1285−-- (fmap (("Odd " ++) . show) FL.length)
1286−-- in S.fold f (S.enumerateFromTo 1 100)
1293+-- >>> :{
1294+-- let f = Fold.partitionBy (\n -> if even n then Left n else Right n)
1295+-- (fmap (("Even " ++) . show) Fold.length)
1296+-- (fmap (("Odd " ++) . show) Fold.length)
1297+-- in Stream.fold f (Stream.enumerateFromTo 1 100)
1298+-- :}
12871299-- ("Even 50","Odd 50")
1288−-- @
12891300--
12901301-- @since 0.7.0
12911302{-# INLINE partitionBy #-}
@@ -1355,12 +1366,13 @@ demuxWith f kv = fmap fst $ demuxDefaultWith f kv drain
13551366-- key into a map from keys to the results of fold outputs of the corresponding
13561367-- values.
13571368--
1358−-- @
1359−-- > let table = Data.Map.fromList [(\"SUM", FL.sum), (\"PRODUCT", FL.product)]
1360−-- input = S.fromList [(\"SUM",1),(\"PRODUCT",2),(\"SUM",3),(\"PRODUCT",4)]
1361−-- in S.fold (FL.demux table) input
1369+-- >>> import qualified Data.Map
1370+-- >>> :{
1371+-- let table = Data.Map.fromList [("SUM", Fold.sum), ("PRODUCT", Fold.product)]
1372+-- input = Stream.fromList [("SUM",1),("PRODUCT",2),("SUM",3),("PRODUCT",4)]
1373+-- in Stream.fold (Fold.demux table) input
1374+-- :}
13621375-- fromList [("PRODUCT",8),("SUM",4)]
1363−-- @
13641376--
13651377-- @since 0.7.0
13661378{-# INLINE demux #-}
@@ -1505,11 +1517,11 @@ demuxDefault = demuxDefaultWith id
15051517-- given fold. Useful for map/reduce, bucketizing the input in different bins
15061518-- or for generating histograms.
15071519--
1508−-- @
1509−-- > let input = S.fromList [(\"ONE",1),(\"ONE",1.1),(\"TWO",2), (\"TWO",2.2)]
1510−-- in S.fold (FL.classify FL.toList) input
1511−-- fromList [(\"ONE",[1.1,1.0]),(\"TWO",[2.2,2.0])]
1512−-- @
1520+-- >>> :{
1521+-- let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
1522+-- in Stream.fold (Fold.classifyWith fst (Fold.map snd Fold.toList)) input
1523+-- :}
1524+-- fromList [("ONE",[1.0,1.1]),("TWO",[2.0,2.2])]
15131525--
15141526-- If the classifier fold stops for a particular key any further inputs in that
15151527-- bucket are ignored.
@@ -1564,14 +1576,14 @@ classifyWith f (Fold step1 initial1 extract1) = mkAccumM step initial extract
15641576-- the values belonging to each key. Useful for map/reduce, bucketizing the
15651577-- input in different bins or for generating histograms.
15661578--
1567−-- @
1568−-- > let input = S.fromList [(\"ONE",1),(\"ONE",1.1),(\"TWO",2), (\"TWO",2.2)]
1569−-- in S.fold (FL.classify FL.toList) input
1570−-- fromList [(\"ONE",[1.1,1.0]),(\"TWO",[2.2,2.0])]
1571−-- @
1579+-- >>> :{
1580+-- let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
1581+-- in Stream.fold (Fold.classify Fold.toList) input
1582+-- :}
1583+-- fromList [("ONE",[1.0,1.1]),("TWO",[2.0,2.2])]
15721584--
15731585-- @since 0.7.0
1574−
1586+--
15751587-- Same as:
15761588--
15771589-- > classify fld = classifyWith fst (map snd fld)
src/Streamly/Internal/Data/Fold/Types.hs+14−3
@@ -247,6 +247,13 @@ import Streamly.Internal.Data.SVar (MonadAsync)
247247
248248import Prelude hiding (concatMap, filter, map)
249249
250+-- $setup
251+-- >>> :m
252+-- >>> import Prelude hiding (concatMap, filter, map)
253+-- >>> import qualified Streamly.Prelude as Stream
254+-- >>> import qualified Streamly.Data.Fold as Fold
255+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
256+
250257------------------------------------------------------------------------------
251258-- Monadic left folds
252259------------------------------------------------------------------------------
@@ -693,7 +700,8 @@ data ConcatMapState m sa a c
693700--
694701-- Compare with 'Monad' instance method '>>='.
695702--
696−-- >>> Stream.fold (concatMap (flip Fold.takeLE Fold.sum) (Fold.rmapM (return . fromJust) Fold.head)) $ Stream.fromList [10,9..1]
703+-- >>> import Data.Maybe (fromJust)
704+-- >>> Stream.fold (Fold.concatMap (flip Fold.takeLE Fold.sum) (Fold.rmapM (return . fromJust) Fold.head)) $ Stream.fromList [10,9..1]
697705-- 45
698706--
699707-- /Internal/
@@ -848,7 +856,7 @@ instance (Monad m, Floating b) => Floating (Fold m a b) where
848856
849857-- | @(map f fold)@ maps the function @f@ on the input of the fold.
850858--
851−-- >>> S.fold (FL.map (\x -> x * x) FL.sum) (S.enumerateFromTo 1 100)
859+-- >>> Stream.fold (Fold.map (\x -> x * x) Fold.sum) (Stream.enumerateFromTo 1 100)
852860-- 338350
853861--
854862-- __Note__: This is not the same as 'fmap'. @map@ is contravariant where as
@@ -876,9 +884,12 @@ lmapM f (Fold step begin done) = Fold step' begin done
876884
877885-- | Include only those elements that pass a predicate.
878886--
879−-- >>> S.fold (filter (> 5) FL.sum) [1..10]
887+-- >>> Stream.fold (Fold.filter (> 5) Fold.sum) $ Stream.fromList [1..10]
880888-- 40
881889--
890+-- >>> Stream.fold (Fold.filter (< 5) Fold.sum) $ Stream.fromList [1..10]
891+-- 10
892+--
882893-- @since 0.7.0
883894{-# INLINABLE filter #-}
884895filter :: Monad m => (a -> Bool) -> Fold m a r -> Fold m a r
src/Streamly/Internal/Data/Parser.hs+78−52
@@ -206,6 +206,15 @@ import qualified Streamly.Internal.Data.Fold.Types as FL
206206import qualified Streamly.Internal.Data.Parser.ParserD as D
207207import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
208208
209+--
210+-- $setup
211+-- >>> :m
212+-- >>> import Prelude hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
213+-- >>> import qualified Streamly.Prelude as Stream
214+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, parseMany)
215+-- >>> import qualified Streamly.Data.Fold as Fold
216+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
217+
209218-------------------------------------------------------------------------------
210219-- Upgrade folds to parses
211220-------------------------------------------------------------------------------
@@ -276,7 +285,7 @@ dieM = K.toParserK . D.dieM
276285-- | Peek the head element of a stream, without consuming it. Fails if it
277286-- encounters end of input.
278287--
279−-- >>> S.parse ((,) <$> PR.peek <*> PR.satisfy (> 0)) $ S.fromList [1]
288+-- >>> Stream.parse ((,) <$> Parser.peek <*> Parser.satisfy (> 0)) $ Stream.fromList [1]
280289-- (1,1)
281290--
282291-- @
@@ -291,8 +300,8 @@ peek = K.toParserK D.peek
291300
292301-- | Succeeds if we are at the end of input, fails otherwise.
293302--
294−-- >>> S.parse ((,) <$> PR.satisfy (> 0) <*> PR.eof) $ S.fromList [1]
295−-- > (1,())
303+-- >>> Stream.parse ((,) <$> Parser.satisfy (> 0) <*> Parser.eof) $ Stream.fromList [1]
304+-- (1,())
296305--
297306-- /Internal/
298307--
@@ -302,8 +311,8 @@ eof = K.toParserK D.eof
302311
303312-- | Returns the next element if it passes the predicate, fails otherwise.
304313--
305−-- >>> S.parse (PR.satisfy (== 1)) $ S.fromList [1,0,1]
306−-- > 1
314+-- >>> Stream.parse (Parser.satisfy (== 1)) $ Stream.fromList [1,0,1]
315+-- 1
307316--
308317-- /Internal/
309318--
@@ -344,24 +353,27 @@ either = K.toParserK . D.either
344353-- Examples: -
345354--
346355-- @
347−-- takeBetween' low high ls = S.parse prsr (S.fromList ls)
348−-- where prsr = P.takeBetween low high FL.toList
356+-- >>> :{
357+-- takeBetween' low high ls = Stream.parse prsr (Stream.fromList ls)
358+-- where prsr = Parser.takeBetween low high Fold.toList
359+-- :}
360+--
349361-- @
350362--
351363-- >>> takeBetween' 2 4 [1, 2, 3, 4, 5]
352−-- > [1,2,3,4]
364+-- [1,2,3,4]
353365--
354366-- >>> takeBetween' 2 4 [1, 2]
355−-- > [1,2]
367+-- [1,2]
356368--
357369-- >>> takeBetween' 2 4 [1]
358−-- > ParseError "takeBetween: Expecting alteast 2 elements, got 1"
370+-- *** Exception: ParseError "takeBetween: Expecting alteast 2 elements, got 1"
359371--
360372-- >>> takeBetween' 0 0 [1, 2]
361−-- > []
373+-- []
362374--
363375-- >>> takeBetween' 0 1 []
364−-- > []
376+-- []
365377--
366378-- @takeBetween@ is the most general take operation, other take operations can
367379-- be defined in terms of takeBetween. For example:
@@ -386,8 +398,8 @@ takeBetween m n = K.toParserK . D.takeBetween m n
386398-- * Fails - if the stream or the collecting fold ends before it can collect
387399-- exactly @n@ elements.
388400--
389−-- >>> S.parse (PR.takeEQ 4 FL.toList) $ S.fromList [1,0,1]
390−-- > "takeEQ: Expecting exactly 4 elements, got 3"
401+-- >>> Stream.parse (Parser.takeEQ 4 Fold.toList) $ Stream.fromList [1,0,1]
402+-- *** Exception: ParseError "takeEQ: Expecting exactly 4 elements, input terminated on 3"
391403--
392404-- /Internal/
393405--
@@ -401,11 +413,11 @@ takeEQ n = K.toParserK . D.takeEQ n
401413-- * Fails - if the stream or the collecting fold ends before producing @n@
402414-- elements.
403415--
404−-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
405−-- > "takeGE: Expecting at least 4 elements, got only 3"
416+-- >>> Stream.parse (Parser.takeGE 4 Fold.toList) $ Stream.fromList [1,0,1]
417+-- *** Exception: ParseError "takeGE: Expecting at least 4 elements, input terminated on 3"
406418--
407−-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1,0,1]
408−-- > [1,0,1,0,1]
419+-- >>> Stream.parse (Parser.takeGE 4 Fold.toList) $ Stream.fromList [1,0,1,0,1]
420+-- [1,0,1,0,1]
409421--
410422-- /Internal/
411423--
@@ -443,8 +455,8 @@ takeWhileP _cond = undefined -- K.toParserK . D.takeWhileP cond
443455-- * Stops - when the predicate fails or the collecting fold stops.
444456-- * Fails - never.
445457--
446−-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
447−-- > [0,0]
458+-- >>> Stream.parse (Parser.takeWhile (== 0) Fold.toList) $ Stream.fromList [0,0,1,0,1]
459+-- [0,0]
448460--
449461-- We can implement a @breakOn@ using 'takeWhile':
450462--
@@ -518,22 +530,24 @@ sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond
518530--
519531-- Examples: -
520532--
521−-- @
522−-- sliceBeginWithOdd ls = S.parse prsr (S.fromList ls)
523−-- where prsr = P.sliceBeginWith odd FL.toList
524−-- @
533+-- >>> :{
534+-- sliceBeginWithOdd ls = Stream.parse prsr (Stream.fromList ls)
535+-- where prsr = Parser.sliceBeginWith odd Fold.toList
536+-- :}
537+--
525538--
526539-- >>> sliceBeginWithOdd [2, 4, 6, 3]
527−-- > [2,4,6]
540+-- *** Exception: sliceBeginWith : slice begins with an element which fails the predicate
541+-- ...
528542--
529543-- >>> sliceBeginWithOdd [3, 5, 7, 4]
530−-- > [3]
544+-- [3]
531545--
532546-- >>> sliceBeginWithOdd [3, 4, 6, 8, 5]
533−-- > [3,4,6,8]
547+-- [3,4,6,8]
534548--
535549-- >>> sliceBeginWithOdd []
536−-- > []
550+-- []
537551--
538552-- /Internal/
539553--
@@ -560,17 +574,20 @@ escapedSliceSepBy _cond _esc = undefined
560574--
561575-- For example,
562576--
563−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello}"
564−-- > "hello"
577+-- @
578+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello}"
579+-- "hello"
580+--
581+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello {world}}"
582+-- "hello world"
565583--
566−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello {world}}"
567−-- > "hello world"
584+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello \\{world\\}}"
585+-- "hello {world}"
568586--
569−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello \\{world\\}}"
570−-- > "hello {world}"
587+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello {world}"
588+-- ParseError "Unterminated '{'"
571589--
572−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello {world}"
573−-- > ParseError "Unterminated '{'"
590+-- @
574591--
575592-- /Unimplemented/
576593{-# INLINABLE escapedFrameBy #-}
@@ -605,10 +622,12 @@ wordBy f = K.toParserK . D.wordBy f
605622-- * Stops - when the comparison fails.
606623-- * Fails - never.
607624--
608−-- > runGroupsBy eq =
609−-- > Stream.toList
610−-- > . Stream.parseMany (groupBy eq Fold.toList)
611−-- > . Stream.fromList
625+-- >>> :{
626+-- runGroupsBy eq =
627+-- Stream.toList
628+-- . Stream.parseMany (Parser.groupBy eq Fold.toList)
629+-- . Stream.fromList
630+-- :}
612631--
613632-- >>> runGroupsBy (<) []
614633-- []
@@ -617,7 +636,7 @@ wordBy f = K.toParserK . D.wordBy f
617636-- [[1]]
618637--
619638-- >>> runGroupsBy (<) [3, 5, 4, 1, 2, 0]
620−-- [[3, 5, 4], [1, 2], [0]]
639+-- [[3,5,4],[1,2],[0]]
621640--
622641-- /Internal/
623642--
@@ -637,10 +656,12 @@ groupBy eq = K.toParserK . D.groupBy eq
637656-- * Stops - when the comparison fails.
638657-- * Fails - never.
639658--
640−-- > runGroupsByRolling eq =
641−-- > Stream.toList
642−-- > . Stream.parseMany (groupByRolling eq Fold.toList)
643−-- > . Stream.fromList
659+-- >>> :{
660+-- runGroupsByRolling eq =
661+-- Stream.toList
662+-- . Stream.parseMany (Parser.groupByRolling eq Fold.toList)
663+-- . Stream.fromList
664+-- :}
644665--
645666-- >>> runGroupsByRolling (<) []
646667-- []
@@ -649,7 +670,7 @@ groupBy eq = K.toParserK . D.groupBy eq
649670-- [[1]]
650671--
651672-- >>> runGroupsByRolling (<) [3, 5, 4, 1, 2, 0]
652−-- [[3, 5], [4], [1, 2], [0]]
673+-- [[3,5],[4],[1,2],[0]]
653674--
654675-- /Internal/
655676--
@@ -659,10 +680,10 @@ groupByRolling eq = K.toParserK . D.groupByRolling eq
659680
660681-- | Match the given sequence of elements using the given comparison function.
661682--
662−-- >>> S.parse $ S.eqBy (==) "string" $ S.fromList "string"
683+-- >>> Stream.parse (Parser.eqBy (==) "string") $ Stream.fromList "string"
663684--
664−-- >>> S.parse $ S.eqBy (==) "mismatch" $ S.fromList "match"
665−-- > *** Exception: ParseError "eqBy: failed, yet to match 7 elements"
685+-- >>> Stream.parse (Parser.eqBy (==) "mismatch") $ Stream.fromList "match"
686+-- *** Exception: ParseError "eqBy: failed, yet to match 7 elements"
666687--
667688-- /Internal/
668689--
@@ -687,7 +708,9 @@ eqBy cmp = K.toParserK . D.eqBy cmp
687708-- This implementation is strict in the second argument, therefore, the
688709-- following will fail:
689710--
690−-- >>> S.parse (PR.splitWith const (PR.satisfy (> 0)) undefined) $ S.fromList [1]
711+-- >>> Stream.parse (Parser.splitWith const (Parser.satisfy (> 0)) undefined) $ Stream.fromList [1]
712+-- *** Exception: Prelude.undefined
713+-- ...
691714--
692715-- Compare with 'Applicative' instance method '<*>'. This implementation allows
693716-- stream fusion but has quadratic complexity. This can fuse with other
@@ -729,7 +752,9 @@ splitWith f p1 p2 =
729752-- This implementation is strict in the second argument, therefore, the
730753-- following will fail:
731754--
732−-- >>> S.parse (split_ (PR.satisfy (> 0)) undefined) $ S.fromList [1]
755+-- >>> Stream.parse (Parser.split_ (Parser.satisfy (> 0)) undefined) $ Stream.fromList [1]
756+-- *** Exception: Prelude.undefined
757+-- ...
733758--
734759-- Compare with 'Applicative' instance method '*>'. This implementation allows
735760-- stream fusion but has quadratic complexity. This can fuse with other
@@ -783,7 +808,8 @@ teeWithMin f p1 p2 =
783808-- Note: This implementation is not lazy in the second argument. The following
784809-- will fail:
785810--
786−-- >>> S.parse (PR.satisfy (> 0) `PR.alt` undefined) $ S.fromList [1..10]
811+-- >>> Stream.parse (Parser.satisfy (> 0) `Parser.alt` undefined) $ Stream.fromList [1..10]
812+-- 1
787813--
788814-- Compare with 'Alternative' instance method '<|>'. This implementation allows
789815-- stream fusion but has quadratic complexity. This can fuse with other
src/Streamly/Internal/Data/Parser/ParserD.hs+20−8
@@ -172,6 +172,15 @@ import Prelude hiding
172172import Streamly.Internal.Data.Parser.ParserD.Tee
173173import Streamly.Internal.Data.Parser.ParserD.Types
174174
175+--
176+-- $setup
177+-- >>> :m
178+-- >>> import Prelude hiding ()
179+-- >>> import qualified Streamly.Prelude as Stream
180+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
181+-- >>> import qualified Streamly.Data.Fold as Fold
182+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
183+
175184-------------------------------------------------------------------------------
176185-- Upgrade folds to parses
177186-------------------------------------------------------------------------------
@@ -571,7 +580,7 @@ sliceBeginWith cond (Fold fstep finitial fextract) =
571580 step (Left' s) a =
572581 if cond a
573582 then process s a
574− else error $ "sliceBeginWith : slice begins with an element which"
583+ else error $ "sliceBeginWith : slice begins with an element which "
575584 ++ "fails the predicate"
576585 step (Right' s) a =
577586 if not (cond a)
@@ -739,16 +748,19 @@ eqBy cmp str = Parser step initial extract
739748-- input as long as the predicate @p@ is 'True'. @f2@ consumes the rest of the
740749-- input.
741750--
742−-- > let span_ p xs = S.parse (FL.span p FL.toList FL.toList) $ S.fromList xs
751+-- @
752+-- > let span_ p xs = Stream.parse (Parser.span p Fold.toList Fold.toList) $ Stream.fromList xs
753+--
754+-- > span_ (< 1) [1,2,3]
755+-- ([],[1,2,3])
743756--
744−-- >>> span_ (< 1) [1,2,3]
745−-- > ([],[1,2,3])
757+-- > span_ (< 2) [1,2,3]
758+-- ([1],[2,3])
746759--
747−-- >>> span_ (< 2) [1,2,3]
748−-- > ([1],[2,3])
760+-- > span_ (< 4) [1,2,3]
761+-- ([1,2,3],[])
749762--
750−-- >>> span_ (< 4) [1,2,3]
751−-- > ([1,2,3],[])
763+-- @
752764--
753765-- /Internal/
754766{-# INLINE span #-}
src/Streamly/Internal/Data/Parser/ParserD/Types.hs+10−1
@@ -142,6 +142,14 @@ import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
142142import qualified Streamly.Internal.Data.Fold.Types as FL
143143
144144import Prelude hiding (concatMap)
145+--
146+-- $setup
147+-- >>> :m
148+-- >>> import Control.Applicative ((<|>))
149+-- >>> import Prelude hiding (concatMap)
150+-- >>> import qualified Streamly.Prelude as Stream
151+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
152+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
145153
146154-- | The return type of a 'Parser' step.
147155--
@@ -634,7 +642,8 @@ dieM err =
634642-- Note: The implementation of '<|>' is not lazy in the second
635643-- argument. The following code will fail:
636644--
637−-- >>> S.parse (PR.satisfy (> 0) <|> undefined) $ S.fromList [1..10]
645+-- >>> Stream.parse (Parser.satisfy (> 0) <|> undefined) $ Stream.fromList [1..10]
646+-- 1
638647--
639648instance MonadCatch m => Alternative (Parser m a) where
640649 {-# INLINE empty #-}
src/Streamly/Internal/Data/Stream/IsStream/Common.hs+40−35
@@ -74,6 +74,15 @@ import qualified Streamly.Internal.Data.Stream.StreamD as S
7474
7575import Prelude hiding (take, takeWhile, drop, reverse)
7676
77+--
78+-- $setup
79+-- >>> :m
80+-- >>> import Prelude hiding (take, takeWhile, drop, reverse)
81+-- >>> import qualified Streamly.Prelude as Stream
82+-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
83+-- >>> import qualified Streamly.Data.Fold as Fold
84+-- >>> import qualified Streamly.Data.Array.Foreign as Array
85+
7786------------------------------------------------------------------------------
7887-- Generation
7988------------------------------------------------------------------------------
@@ -112,7 +121,7 @@ yield = K.yield
112121-- Create a singleton stream from a monadic action.
113122--
114123-- @
115−-- > toList $ yieldM getLine
124+-- > Stream.toList $ Stream.yieldM getLine
116125-- hello
117126-- ["hello"]
118127-- @
@@ -159,12 +168,12 @@ repeatMSerial = fromStreamS . S.repeatM
159168-- A lower granularity clock gives higher precision but is more expensive in
160169-- terms of CPU usage. Any granularity lower than 1 ms is treated as 1 ms.
161170--
162−-- @
163−-- >>> S.mapM_ (\x -> print x >> threadDelay 1000000) $ S.timesWith 0.01
164−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 0))
165−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1002028000))
166−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1996656000))
167−-- @
171+-- >>> import Control.Concurrent (threadDelay)
172+-- >>> import Streamly.Internal.Data.Stream.IsStream.Common as Stream (timesWith)
173+-- >>> Stream.mapM_ (\x -> print x >> threadDelay 1000000) $ Stream.take 3 $ Stream.timesWith 0.01
174+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
175+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
176+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
168177--
169178-- Note: This API is not safe on 32-bit machines.
170179--
@@ -179,9 +188,10 @@ timesWith g = fromStreamD $ D.times g
179188-- expensive in terms of CPU usage. Any granularity lower than 1 ms is treated
180189-- as 1 ms.
181190--
182−-- @
183−-- >>> S.mapM_ print $ S.delayPre 1 $ S.absTimesWith 0.01
184−-- @
191+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ absTimesWith 0.01
192+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
193+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
194+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
185195--
186196-- Note: This API is not safe on 32-bit machines.
187197--
@@ -197,12 +207,10 @@ absTimesWith = fmap (uncurry addToAbsTime64) . timesWith
197207-- clock is more expensive in terms of CPU usage. Any granularity lower than 1
198208-- ms is treated as 1 ms.
199209--
200−-- @
201−-- >>> S.mapM_ print $ S.delayPre 1 $ S.relTimesWith 0.01
202−-- > RelTime64 (NanoSecond64 0)
203−-- > RelTime64 (NanoSecond64 91139000)
204−-- > RelTime64 (NanoSecond64 204052000)
205−-- @
210+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimesWith 0.01
211+-- RelTime64 (NanoSecond64 ...)
212+-- RelTime64 (NanoSecond64 ...)
213+-- RelTime64 (NanoSecond64 ...)
206214--
207215-- Note: This API is not safe on 32-bit machines.
208216--
@@ -222,7 +230,7 @@ relTimesWith = fmap snd . timesWith
222230-- 'Fold' can terminate early without consuming the full stream. See the
223231-- documentation of individual 'Fold's for termination behavior.
224232--
225−-- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
233+-- >>> Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
226234-- 5050
227235--
228236-- @fold f = parse (Parser.fromFold f)@
@@ -368,10 +376,8 @@ findIndices p m = fromStreamS $ S.findIndices p (toStreamS m)
368376-- | Insert an effect and its output before consuming an element of a stream
369377-- except the first one.
370378--
371−-- @
372−-- >>> S.toList $ S.trace putChar $ S.intersperseM (putChar '.' >> return ',') $ S.fromList "hello"
373−-- > h.,e.,l.,l.,o"h,e,l,l,o"
374−-- @
379+-- >>> Stream.toList $ Stream.trace putChar $ Stream.intersperseM (putChar '.' >> return ',') $ Stream.fromList "hello"
380+-- h.,e.,l.,l.,o"h,e,l,l,o"
375381--
376382-- @since 0.5.0
377383{-# INLINE intersperseM #-}
@@ -382,8 +388,9 @@ intersperseM m = fromStreamS . S.intersperseM m . toStreamS
382388-- seconds.
383389--
384390-- @
385−-- > S.drain $ S.interjectSuffix 1 (putChar ',') $ S.mapM (\\x -> threadDelay 1000000 >> putChar x) $ S.fromList "hello"
386−-- "h,e,l,l,o"
391+-- > import Control.Concurrent (threadDelay)
392+-- > Stream.drain $ Stream.interjectSuffix 1 (putChar ',') $ Stream.mapM (\x -> threadDelay 1000000 >> putChar x) $ Stream.fromList "hello"
393+-- h,e,l,l,o
387394-- @
388395--
389396-- /Internal/
@@ -463,36 +470,34 @@ concatM generator = concatMapM (\() -> generator) (yield ())
463470--
464471-- For illustration, let's define a function that operates on pure lists:
465472--
466−-- @
467−-- splitOnSeq' pat xs = S.toList $ S.splitOnSeq (A.fromList pat) (FL.toList) (S.fromList xs)
468−-- @
473+-- >>> splitOnSeq' pat xs = Stream.toList $ Stream.splitOnSeq (Array.fromList pat) Fold.toList (Stream.fromList xs)
469474--
470475-- >>> splitOnSeq' "" "hello"
471−-- > ["h","e","l","l","o"]
476+-- ["h","e","l","l","o"]
472477--
473478-- >>> splitOnSeq' "hello" ""
474−-- > [""]
479+-- [""]
475480--
476481-- >>> splitOnSeq' "hello" "hello"
477−-- > ["",""]
482+-- ["",""]
478483--
479484-- >>> splitOnSeq' "x" "hello"
480−-- > ["hello"]
485+-- ["hello"]
481486--
482487-- >>> splitOnSeq' "h" "hello"
483−-- > ["","ello"]
488+-- ["","ello"]
484489--
485490-- >>> splitOnSeq' "o" "hello"
486−-- > ["hell",""]
491+-- ["hell",""]
487492--
488493-- >>> splitOnSeq' "e" "hello"
489−-- > ["h","llo"]
494+-- ["h","llo"]
490495--
491496-- >>> splitOnSeq' "l" "hello"
492−-- > ["he","","o"]
497+-- ["he","","o"]
493498--
494499-- >>> splitOnSeq' "ll" "hello"
495−-- > ["he","o"]
500+-- ["he","o"]
496501--
497502-- 'splitOnSeq' is an inverse of 'intercalate'. The following law always holds:
498503--
src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+9−2
@@ -177,6 +177,13 @@ import Prelude hiding
177177 , null , reverse, init, and, or, lookup, foldr1, (!!) , splitAt, break
178178 , mconcat)
179179
180+-- $setup
181+-- >>> :m
182+-- >>> import qualified Streamly.Prelude as Stream
183+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
184+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
185+-- >>> import qualified Streamly.Data.Fold as Fold
186+
180187------------------------------------------------------------------------------
181188-- Deconstruction
182189------------------------------------------------------------------------------
@@ -212,8 +219,8 @@ uncons m = K.uncons (K.adapt m)
212219--
213220-- Example, determine if any element is 'odd' in a stream:
214221--
215−-- >>> S.foldrM (\x xs -> if odd x then return True else xs) (return False) $ S.fromList (2:4:5:undefined)
216−-- > True
222+-- >>> Stream.foldrM (\x xs -> if odd x then return True else xs) (return False) $ Stream.fromList (2:4:5:undefined)
223+-- True
217224--
218225-- /Since: 0.7.0 (signature changed)/
219226--
src/Streamly/Internal/Data/Stream/IsStream/Generate.hs+25−16
@@ -116,13 +116,24 @@ import qualified System.IO as IO
116116
117117import Prelude hiding (iterate, replicate, repeat)
118118
119+-- $setup
120+-- >>> :m
121+-- >>> import Prelude hiding (iterate, replicate, repeat)
122+-- >>> import qualified Streamly.Prelude as Stream
123+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
124+-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
125+-- >>> import Control.Concurrent (threadDelay)
126+
119127------------------------------------------------------------------------------
120128-- From Unfold
121129------------------------------------------------------------------------------
122130
123131-- | Convert an 'Unfold' into a stream by supplying it an input seed.
124132--
125−-- >>> unfold (UF.replicateM 10) (putStrLn "hello")
133+-- >>> Stream.drain $ Stream.unfold (Unfold.replicateM 3) (putStrLn "hello")
134+-- hello
135+-- hello
136+-- hello
126137--
127138-- /Since: 0.7.0/
128139{-# INLINE unfold #-}
@@ -278,12 +289,10 @@ replicateMSerial n = fromStreamS . S.replicateM n
278289-- (epoch) denoting the start of the stream and the second component is a time
279290-- relative to the reference.
280291--
281−-- @
282−-- >>> S.mapM_ (\x -> print x >> threadDelay 1000000) $ S.times
283−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 0))
284−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1002028000))
285−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1996656000))
286−-- @
292+-- >>> Stream.mapM_ (\x -> print x >> threadDelay 1000000) $ Stream.take 3 $ Stream.times
293+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
294+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
295+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
287296--
288297-- Note: This API is not safe on 32-bit machines.
289298--
@@ -296,9 +305,10 @@ times = timesWith 0.01
296305-- | @absTimes@ returns a stream of absolute timestamps using a clock of 10 ms
297306-- granularity.
298307--
299−-- @
300−-- >>> S.mapM_ print $ S.delayPre 1 $ S.absTimes
301−-- @
308+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.absTimes
309+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
310+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
311+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
302312--
303313-- Note: This API is not safe on 32-bit machines.
304314--
@@ -317,9 +327,10 @@ currentTime = absTimesWith
317327-- | @relTimes@ returns a stream of relative time values starting from 0,
318328-- using a clock of granularity 10 ms.
319329--
320−-- @
321−-- >>> S.mapM_ print $ S.delayPre 1 $ S.relTimes
322−-- @
330+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimes
331+-- RelTime64 (NanoSecond64 ...)
332+-- RelTime64 (NanoSecond64 ...)
333+-- RelTime64 (NanoSecond64 ...)
323334--
324335-- Note: This API is not safe on 32-bit machines.
325336--
@@ -386,10 +397,8 @@ timeout = undefined
386397-- Generate an infinite stream, whose values are the output of a function @f@
387398-- applied on the corresponding index. Index starts at 0.
388399--
389−-- @
390−-- > Stream.toList $ Stream.take 5 $ Stream.fromIndices id
400+-- >>> Stream.toList $ Stream.take 5 $ Stream.fromIndices id
391401-- [0,1,2,3,4]
392−-- @
393402--
394403-- @since 0.6.0
395404{-# INLINE fromIndices #-}
src/Streamly/Internal/Data/Stream/IsStream/Nesting.hs+142−102
@@ -303,6 +303,17 @@ import qualified Streamly.Internal.Data.Stream.StreamD as S
303303
304304import Prelude hiding (zipWith, concatMap, concat)
305305
306+-- $setup
307+-- >>> :m
308+-- >>> import Prelude hiding (zipWith, concatMap, concat)
309+-- >>> import qualified Streamly.Prelude as Stream
310+-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
311+-- >>> import qualified Streamly.Data.Fold as Fold
312+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
313+-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
314+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
315+-- >>> import qualified Streamly.Data.Array.Foreign as Array
316+
306317-------------------------------------------------------------------------------
307318-- Appending
308319-------------------------------------------------------------------------------
@@ -339,9 +350,10 @@ append m1 m2 = fromStreamD $ D.append (toStreamD m1) (toStreamD m2)
339350-- early the other stream continues alone until it too finishes.
340351--
341352-- >>> :set -XOverloadedStrings
342−-- >>> interleave "ab" ",,,," :: SerialT Identity Char
353+-- >>> import Data.Functor.Identity (Identity)
354+-- >>> Stream.interleave "ab" ",,,," :: Stream.SerialT Identity Char
343355-- fromList "a,b,,,"
344−-- >>> interleave "abcd" ",," :: SerialT Identity Char
356+-- >>> Stream.interleave "abcd" ",," :: Stream.SerialT Identity Char
345357-- fromList "a,b,cd"
346358--
347359-- 'interleave' is dual to 'interleaveMin', it can be called @interleaveMax@.
@@ -361,9 +373,10 @@ interleave m1 m2 = fromStreamD $ D.interleave (toStreamD m1) (toStreamD m2)
361373-- still continues to yield elements until it finishes.
362374--
363375-- >>> :set -XOverloadedStrings
364−-- >>> interleaveSuffix "abc" ",,,," :: SerialT Identity Char
376+-- >>> import Data.Functor.Identity (Identity)
377+-- >>> Stream.interleaveSuffix "abc" ",,,," :: Stream.SerialT Identity Char
365378-- fromList "a,b,c,"
366−-- >>> interleaveSuffix "abc" "," :: SerialT Identity Char
379+-- >>> Stream.interleaveSuffix "abc" "," :: Stream.SerialT Identity Char
367380-- fromList "a,bc"
368381--
369382-- 'interleaveSuffix' is a dual of 'interleaveInfix'.
@@ -384,9 +397,10 @@ interleaveSuffix m1 m2 =
384397-- has finished.
385398--
386399-- >>> :set -XOverloadedStrings
387−-- >>> interleaveInfix "abc" ",,,," :: SerialT Identity Char
400+-- >>> import Data.Functor.Identity (Identity)
401+-- >>> Stream.interleaveInfix "abc" ",,,," :: Stream.SerialT Identity Char
388402-- fromList "a,b,c"
389−-- >>> interleaveInfix "abc" "," :: SerialT Identity Char
403+-- >>> Stream.interleaveInfix "abc" "," :: Stream.SerialT Identity Char
390404-- fromList "a,bc"
391405--
392406-- 'interleaveInfix' is a dual of 'interleaveSuffix'.
@@ -406,9 +420,10 @@ interleaveInfix m1 m2 =
406420-- stream.
407421--
408422-- >>> :set -XOverloadedStrings
409−-- >>> interleaveMin "ab" ",,,," :: SerialT Identity Char
423+-- >>> import Data.Functor.Identity (Identity)
424+-- >>> Stream.interleaveMin "ab" ",,,," :: Stream.SerialT Identity Char
410425-- fromList "a,b,"
411−-- >>> interleaveMin "abcd" ",," :: SerialT Identity Char
426+-- >>> Stream.interleaveMin "abcd" ",," :: Stream.SerialT Identity Char
412427-- fromList "a,b,c"
413428--
414429-- 'interleaveMin' is dual to 'interleave'.
@@ -453,8 +468,9 @@ roundrobin m1 m2 = fromStreamD $ D.roundRobin (toStreamD m1) (toStreamD m2)
453468-- also remain sorted in ascending order.
454469--
455470-- @
456−-- > S.toList $ S.mergeBy compare (S.fromList [1,3,5]) (S.fromList [2,4,6,8])
471+-- >>> Stream.toList $ Stream.mergeBy compare (Stream.fromList [1,3,5]) (Stream.fromList [2,4,6,8])
457472-- [1,2,3,4,5,6,8]
473+--
458474-- @
459475--
460476-- @since 0.6.0
@@ -763,10 +779,10 @@ gintercalate unf1 str1 unf2 str2 =
763779--
764780-- | 'intersperse' followed by unfold and concat.
765781--
766−-- > unwords = intercalate " " UF.fromList
782+-- > unwords = intercalate " " Unfold.fromList
767783--
768−-- >>> intercalate " " UF.fromList ["abc", "def", "ghi"]
769−-- > "abc def ghi"
784+-- >>> Stream.toList $ Stream.intercalate " " Unfold.fromList $ Stream.fromList ["abc", "def", "ghi"]
785+-- "abc def ghi"
770786--
771787-- /Internal/
772788{-# INLINE intercalate #-}
@@ -792,10 +808,10 @@ gintercalateSuffix unf1 str1 unf2 str2 =
792808--
793809-- | 'intersperseSuffix' followed by unfold and concat.
794810--
795−-- > unlines = intercalateSuffix "\n" UF.fromList
811+-- > unlines = intercalateSuffix "\n" Unfold.fromList
796812--
797−-- >>> intercalate "\n" UF.fromList ["abc", "def", "ghi"]
798−-- > "abc\ndef\nghi\n"
813+-- >>> Stream.toList $ Stream.intercalateSuffix "\n" Unfold.fromList $ Stream.fromList ["abc", "def", "ghi"]
814+-- "abc\ndef\nghi\n"
799815--
800816-- /Internal/
801817{-# INLINE intercalateSuffix #-}
@@ -932,11 +948,11 @@ iterateMapLeftsWith combine f = iterateMapWith combine (either f (const K.nil))
932948--
933949-- >>> f = Fold.takeLE 2 Fold.sum
934950-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList []
935−-- > [0]
951+-- [0]
936952-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList [1..9]
937−-- > [3,7,11,15,9]
953+-- [3,7,11,15,9]
938954-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList [1..10]
939−-- > [3,7,11,15,19,0]
955+-- [3,7,11,15,19,0]
940956--
941957-- /Internal/
942958--
@@ -955,12 +971,12 @@ foldManyPost f m = D.fromStreamD $ D.foldManyPost f (D.toStreamD m)
955971--
956972-- >>> f = Fold.takeLE 2 Fold.sum
957973-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList [1..10]
958−-- > [3,7,11,15,19]
974+-- [3,7,11,15,19]
959975--
960976-- On an empty stream the output is empty:
961977--
962978-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList []
963−-- > []
979+-- []
964980--
965981-- Note @foldMany (takeLE 0)@ would result in an infinite loop in a non-empty
966982-- stream.
@@ -992,10 +1008,14 @@ foldSequence _f _m = undefined
9921008-- generate the first fold, the fold is applied on the stream and the result of
9931009-- the fold is used to generate the next fold and so on.
9941010--
995−-- >>> f x = Fold.takeLE 2 (Fold.mconcatTo x)
996−-- >>> s = Stream.map Sum $ Stream.fromList [1..10]
997−-- >>> Stream.toList $ Stream.map getSum $ Stream.foldIterate f 0 s
998−-- > [3,10,21,36,55,55]
1011+-- @
1012+-- > import Data.Monoid (Sum(..))
1013+-- > f x = Fold.takeLE 2 (Fold.sconcat x)
1014+-- > s = Stream.map Sum $ Stream.fromList [1..10]
1015+-- > Stream.toList $ Stream.map getSum $ Stream.foldIterate f 0 s
1016+-- [3,10,21,36,55,55]
1017+--
1018+-- @
9991019--
10001020-- This is the streaming equivalent of monad like sequenced application of
10011021-- folds where next fold is dependent on the previous fold.
@@ -1022,11 +1042,14 @@ foldIterate _f _i _m = undefined
10221042-- This is the streaming equivalent of the 'Streamly.Internal.Data.Parser.many'
10231043-- parse combinator.
10241044--
1025−-- >>> S.toList $ S.parseMany (PR.take 2 $ PR.fromFold FL.sum) $ S.fromList [1..10]
1026−-- > [3,7,11,15,19]
1045+-- >>> Stream.toList $ Stream.parseMany (Parser.takeBetween 0 2 Fold.sum) $ Stream.fromList [1..10]
1046+-- [3,7,11,15,19]
1047+--
1048+-- @
1049+-- > Stream.toList $ Stream.parseMany (Parser.line Fold.toList) $ Stream.fromList "hello\\nworld"
1050+-- ["hello\\n","world"]
10271051--
1028−-- >>> S.toList $ S.parseMany (PR.line FL.toList) $ S.fromList "hello\nworld"
1029−-- > ["hello\n","world"]
1052+-- @
10301053--
10311054-- @
10321055-- foldMany f = parseMany (fromFold f)
@@ -1089,8 +1112,9 @@ parseManyTill = undefined
10891112-- used to generate the first parser, the parser is applied on the stream and
10901113-- the result is used to generate the next parser and so on.
10911114--
1092−-- >>> S.toList $ S.map getSum $ S.parseIterate (\b -> PR.take 2 (FL.mconcatTo b)) 0 $ S.map Sum $ S.fromList [1..10]
1093−-- > [3,10,21,36,55,55]
1115+-- >>> import Data.Monoid (Sum(..))
1116+-- >>> Stream.toList $ Stream.map getSum $ Stream.parseIterate (\b -> Parser.takeBetween 0 2 (Fold.sconcat b)) 0 $ Stream.map Sum $ Stream.fromList [1..10]
1117+-- [3,10,21,36,55,55]
10941118--
10951119-- This is the streaming equivalent of monad like sequenced application of
10961120-- parsers where next parser is dependent on the previous parser.
@@ -1196,8 +1220,8 @@ groupScan split fold m = undefined
11961220-- group is folded using the fold @f@ and the result of the fold is emitted in
11971221-- the output stream.
11981222--
1199−-- >>> S.toList $ S.groupsBy (>) FL.toList $ S.fromList [1,3,7,0,2,5]
1200−-- > [[1,3,7],[0,2,5]]
1223+-- >>> Stream.toList $ Stream.groupsBy (>) Fold.toList $ Stream.fromList [1,3,7,0,2,5]
1224+-- [[1,3,7],[0,2,5]]
12011225--
12021226-- @since 0.7.0
12031227{-# INLINE groupsBy #-}
@@ -1217,8 +1241,8 @@ groupsBy cmp f m = D.fromStreamD $ D.groupsBy cmp f (D.toStreamD m)
12171241-- comparison fails a new group is started. Each group is folded using the fold
12181242-- @f@.
12191243--
1220−-- >>> S.toList $ S.groupsByRolling (\a b -> a + 1 == b) FL.toList $ S.fromList [1,2,3,7,8,9]
1221−-- > [[1,2,3],[7,8,9]]
1244+-- >>> Stream.toList $ Stream.groupsByRolling (\a b -> a + 1 == b) Fold.toList $ Stream.fromList [1,2,3,7,8,9]
1245+-- [[1,2,3],[7,8,9]]
12221246--
12231247-- @since 0.7.0
12241248{-# INLINE groupsByRolling #-}
@@ -1236,8 +1260,8 @@ groupsByRolling cmp f m = D.fromStreamD $ D.groupsRollingBy cmp f (D.toStreamD
12361260--
12371261-- Groups contiguous spans of equal elements together in individual groups.
12381262--
1239−-- >>> S.toList $ S.groups FL.toList $ S.fromList [1,1,2,2]
1240−-- > [[1,1],[2,2]]
1263+-- >>> Stream.toList $ Stream.groups Fold.toList $ Stream.fromList [1,1,2,2]
1264+-- [[1,1],[2,2]]
12411265--
12421266-- @since 0.7.0
12431267{-# INLINE groups #-}
@@ -1262,9 +1286,9 @@ groups = groupsBy (==)
12621286-- separator elements determined by the supplied predicate, separator is
12631287-- considered as infixed between two segments:
12641288--
1265−-- >>> splitOn' p xs = S.toList $ S.splitOn p FL.toList (S.fromList xs)
1289+-- >>> splitOn' p xs = Stream.toList $ Stream.splitOn p Fold.toList (Stream.fromList xs)
12661290-- >>> splitOn' (== '.') "a.b"
1267−-- > ["a","b"]
1291+-- ["a","b"]
12681292--
12691293-- An empty stream is folded to the default value of the fold:
12701294--
@@ -1278,13 +1302,13 @@ groups = groupsBy (==)
12781302-- ["",""]
12791303--
12801304-- >>> splitOn' (== '.') ".a"
1281−-- > ["","a"]
1305+-- ["","a"]
12821306--
12831307-- >>> splitOn' (== '.') "a."
1284−-- > ["a",""]
1308+-- ["a",""]
12851309--
12861310-- >>> splitOn' (== '.') "a..b"
1287−-- > ["a","","b"]
1311+-- ["a","","b"]
12881312--
12891313-- splitOn is an inverse of intercalating single element:
12901314--
@@ -1318,12 +1342,12 @@ splitOn predicate f =
13181342-- | Split on a suffixed separator element, dropping the separator. The
13191343-- supplied 'Fold' is applied on the split segments.
13201344--
1321−-- > splitOnSuffix' p xs = S.toList $ S.splitOnSuffix p (FL.toList) (S.fromList xs)
1345+-- >>> splitOnSuffix' p xs = Stream.toList $ Stream.splitOnSuffix p Fold.toList (Stream.fromList xs)
13221346-- >>> splitOnSuffix' (== '.') "a.b."
1323−-- > ["a","b"]
1347+-- ["a","b"]
13241348--
13251349-- >>> splitOnSuffix' (== '.') "a."
1326−-- > ["a"]
1350+-- ["a"]
13271351--
13281352-- An empty stream results in an empty output stream:
13291353--
@@ -1337,7 +1361,7 @@ splitOn predicate f =
13371361-- [""]
13381362--
13391363-- >>> splitOnSuffix' (== '.') "a..b.."
1340−-- > ["a","","b",""]
1364+-- ["a","","b",""]
13411365--
13421366-- A suffix is optional at the end of the stream:
13431367--
@@ -1345,10 +1369,10 @@ splitOn predicate f =
13451369-- ["a"]
13461370--
13471371-- >>> splitOnSuffix' (== '.') ".a"
1348−-- > ["","a"]
1372+-- ["","a"]
13491373--
13501374-- >>> splitOnSuffix' (== '.') "a.b"
1351−-- > ["a","b"]
1375+-- ["a","b"]
13521376--
13531377-- > lines = splitOnSuffix (== '\n')
13541378--
@@ -1371,33 +1395,42 @@ splitOnSuffix predicate f = foldMany (FL.sliceSepBy predicate f)
13711395-- | Split on a prefixed separator element, dropping the separator. The
13721396-- supplied 'Fold' is applied on the split segments.
13731397--
1374−-- >>> splitOnPrefix' p xs = S.toList $ S.splitOnPrefix p (FL.toList) (S.fromList xs)
1375−-- >>> splitOnPrefix' (== '.') ".a.b"
1376−-- > ["a","b"]
1398+-- @
1399+-- > splitOnPrefix' p xs = Stream.toList $ Stream.splitOnPrefix p (Fold.toList) (Stream.fromList xs)
1400+-- > splitOnPrefix' (== '.') ".a.b"
1401+-- ["a","b"]
1402+-- @
13771403--
13781404-- An empty stream results in an empty output stream:
1379−-- >>> splitOnPrefix' (== '.') ""
1405+-- @
1406+-- > splitOnPrefix' (== '.') ""
13801407-- []
1408+-- @
13811409--
13821410-- An empty segment consisting of only a prefix is folded to the default output
13831411-- of the fold:
13841412--
1385−-- >>> splitOnPrefix' (== '.') "."
1413+-- @
1414+-- > splitOnPrefix' (== '.') "."
13861415-- [""]
13871416--
1388−-- >>> splitOnPrefix' (== '.') ".a.b."
1389−-- > ["a","b",""]
1417+-- > splitOnPrefix' (== '.') ".a.b."
1418+-- ["a","b",""]
1419+--
1420+-- > splitOnPrefix' (== '.') ".a..b"
1421+-- ["a","","b"]
13901422--
1391−-- >>> splitOnPrefix' (== '.') ".a..b"
1392−-- > ["a","","b"]
1423+-- @
13931424--
13941425-- A prefix is optional at the beginning of the stream:
13951426--
1396−-- >>> splitOnPrefix' (== '.') "a"
1427+-- @
1428+-- > splitOnPrefix' (== '.') "a"
13971429-- ["a"]
13981430--
1399−-- >>> splitOnPrefix' (== '.') "a.b"
1400−-- > ["a","b"]
1431+-- > splitOnPrefix' (== '.') "a.b"
1432+-- ["a","b"]
1433+-- @
14011434--
14021435-- 'splitOnPrefix' is an inverse of 'intercalatePrefix' with a single element:
14031436--
@@ -1420,16 +1453,16 @@ splitOnPrefix _predicate _f = undefined
14201453-- @["a","b"]@. In other words, its like parsing words from whitespace
14211454-- separated text.
14221455--
1423−-- > wordsBy' p xs = S.toList $ S.wordsBy p (FL.toList) (S.fromList xs)
1456+-- >>> wordsBy' p xs = Stream.toList $ Stream.wordsBy p Fold.toList (Stream.fromList xs)
14241457--
14251458-- >>> wordsBy' (== ',') ""
1426−-- > []
1459+-- []
14271460--
14281461-- >>> wordsBy' (== ',') ","
1429−-- > []
1462+-- []
14301463--
14311464-- >>> wordsBy' (== ',') ",a,,b,"
1432−-- > ["a","b"]
1465+-- ["a","b"]
14331466--
14341467-- > words = wordsBy isSpace
14351468--
@@ -1447,7 +1480,7 @@ wordsBy predicate f m =
14471480-- | Like 'splitOnSuffix' but keeps the suffix attached to the resulting
14481481-- splits.
14491482--
1450−-- > splitWithSuffix' p xs = S.toList $ S.splitWithSuffix p (FL.toList) (S.fromList xs)
1483+-- >>> splitWithSuffix' p xs = Stream.toList $ splitWithSuffix p Fold.toList (Stream.fromList xs)
14511484--
14521485-- >>> splitWithSuffix' (== '.') ""
14531486-- []
@@ -1459,19 +1492,19 @@ wordsBy predicate f m =
14591492-- ["a"]
14601493--
14611494-- >>> splitWithSuffix' (== '.') ".a"
1462−-- > [".","a"]
1495+-- [".","a"]
14631496--
14641497-- >>> splitWithSuffix' (== '.') "a."
1465−-- > ["a."]
1498+-- ["a."]
14661499--
14671500-- >>> splitWithSuffix' (== '.') "a.b"
1468−-- > ["a.","b"]
1501+-- ["a.","b"]
14691502--
14701503-- >>> splitWithSuffix' (== '.') "a.b."
1471−-- > ["a.","b."]
1504+-- ["a.","b."]
14721505--
14731506-- >>> splitWithSuffix' (== '.') "a..b.."
1474−-- > ["a.",".","b.","."]
1507+-- ["a.",".","b.","."]
14751508--
14761509-- @since 0.7.0
14771510
@@ -1529,34 +1562,34 @@ splitOnAny subseq f m = undefined -- D.fromStreamD $ D.splitOnAny f subseq (D.to
15291562--
15301563-- | Like 'splitOnSeq' but splits the separator as well, as an infix token.
15311564--
1532−-- > splitOn'_ pat xs = S.toList $ S.splitOn' (A.fromList pat) (FL.toList) (S.fromList xs)
1565+-- >>> splitOn'_ pat xs = Stream.toList $ Stream.splitBySeq (Array.fromList pat) Fold.toList (Stream.fromList xs)
15331566--
15341567-- >>> splitOn'_ "" "hello"
1535−-- > ["h","","e","","l","","l","","o"]
1568+-- ["h","","e","","l","","l","","o"]
15361569--
15371570-- >>> splitOn'_ "hello" ""
1538−-- > [""]
1571+-- [""]
15391572--
15401573-- >>> splitOn'_ "hello" "hello"
1541−-- > ["","hello",""]
1574+-- ["","hello",""]
15421575--
15431576-- >>> splitOn'_ "x" "hello"
1544−-- > ["hello"]
1577+-- ["hello"]
15451578--
15461579-- >>> splitOn'_ "h" "hello"
1547−-- > ["","h","ello"]
1580+-- ["","h","ello"]
15481581--
15491582-- >>> splitOn'_ "o" "hello"
1550−-- > ["hell","o",""]
1583+-- ["hell","o",""]
15511584--
15521585-- >>> splitOn'_ "e" "hello"
1553−-- > ["h","e","llo"]
1586+-- ["h","e","llo"]
15541587--
15551588-- >>> splitOn'_ "l" "hello"
1556−-- > ["he","l","","l","o"]
1589+-- ["he","l","","l","o"]
15571590--
15581591-- >>> splitOn'_ "ll" "hello"
1559−-- > ["he","ll","o"]
1592+-- ["he","ll","o"]
15601593--
15611594-- /Internal/
15621595{-# INLINE splitBySeq #-}
@@ -1569,7 +1602,7 @@ splitBySeq patt f m =
15691602-- | Like 'splitSuffixBy' but the separator is a sequence of elements, instead
15701603-- of a predicate for a single element.
15711604--
1572−-- > splitOnSuffixSeq_ pat xs = S.toList $ S.splitOnSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
1605+-- >>> splitOnSuffixSeq_ pat xs = Stream.toList $ Stream.splitOnSuffixSeq (Array.fromList pat) Fold.toList (Stream.fromList xs)
15731606--
15741607-- >>> splitOnSuffixSeq_ "." ""
15751608-- []
@@ -1581,19 +1614,19 @@ splitBySeq patt f m =
15811614-- ["a"]
15821615--
15831616-- >>> splitOnSuffixSeq_ "." ".a"
1584−-- > ["","a"]
1617+-- ["","a"]
15851618--
15861619-- >>> splitOnSuffixSeq_ "." "a."
1587−-- > ["a"]
1620+-- ["a"]
15881621--
15891622-- >>> splitOnSuffixSeq_ "." "a.b"
1590−-- > ["a","b"]
1623+-- ["a","b"]
15911624--
15921625-- >>> splitOnSuffixSeq_ "." "a.b."
1593−-- > ["a","b"]
1626+-- ["a","b"]
15941627--
15951628-- >>> splitOnSuffixSeq_ "." "a..b.."
1596−-- > ["a","","b",""]
1629+-- ["a","","b",""]
15971630--
15981631-- > lines = splitOnSuffixSeq "\n"
15991632--
@@ -1627,10 +1660,10 @@ wordsOn subseq f m = undefined -- D.fromStreamD $ D.wordsOn f subseq (D.toStream
16271660
16281661-- | Like 'splitOnSuffixSeq' but keeps the suffix intact in the splits.
16291662--
1630−-- > splitWithSuffixSeq'_ pat xs = S.toList $ S.splitWithSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
1663+-- >>> splitWithSuffixSeq' pat xs = Stream.toList $ Stream.splitWithSuffixSeq (Array.fromList pat) Fold.toList (Stream.fromList xs)
16311664--
16321665-- >>> splitWithSuffixSeq' "." ""
1633−-- [""]
1666+-- []
16341667--
16351668-- >>> splitWithSuffixSeq' "." "."
16361669-- ["."]
@@ -1639,19 +1672,19 @@ wordsOn subseq f m = undefined -- D.fromStreamD $ D.wordsOn f subseq (D.toStream
16391672-- ["a"]
16401673--
16411674-- >>> splitWithSuffixSeq' "." ".a"
1642−-- > [".","a"]
1675+-- [".","a"]
16431676--
16441677-- >>> splitWithSuffixSeq' "." "a."
1645−-- > ["a."]
1678+-- ["a."]
16461679--
16471680-- >>> splitWithSuffixSeq' "." "a.b"
1648−-- > ["a.","b"]
1681+-- ["a.","b"]
16491682--
16501683-- >>> splitWithSuffixSeq' "." "a.b."
1651−-- > ["a.","b."]
1684+-- ["a.","b."]
16521685--
16531686-- >>> splitWithSuffixSeq' "." "a..b.."
1654−-- > ["a.",".","b.","."]
1687+-- ["a.",".","b.","."]
16551688--
16561689-- /Internal/
16571690{-# INLINE splitWithSuffixSeq #-}
@@ -1679,8 +1712,8 @@ splitOnSuffixSeqAny subseq f m = undefined
16791712-- | Group the input stream into groups of @n@ elements each and then fold each
16801713-- group using the provided fold function.
16811714--
1682−-- >> S.toList $ S.chunksOf 2 FL.sum (S.enumerateFromTo 1 10)
1683−-- > [3,7,11,15,19]
1715+-- >>> Stream.toList $ Stream.chunksOf 2 Fold.sum (Stream.enumerateFromTo 1 10)
1716+-- [3,7,11,15,19]
16841717--
16851718-- This can be considered as an n-fold version of 'takeLE' where we apply
16861719-- 'takeLE' repeatedly on the leftover stream until the stream exhausts.
@@ -1718,12 +1751,13 @@ arraysOf n = D.fromStreamD . A.arraysOf n . D.toStreamD
17181751
17191752-- XXX we can implement this by repeatedly applying the 'lrunFor' fold.
17201753-- XXX add this example after fixing the serial stream rate control
1721−-- >>> S.toList $ S.take 5 $ intervalsOf 1 FL.sum $ constRate 2 $ S.enumerateFrom 1
1722−-- > [3,7,11,15,19]
17231754--
17241755-- | Group the input stream into windows of @n@ second each and then fold each
17251756-- group using the provided fold function.
17261757--
1758+-- >>> Stream.toList $ Stream.take 5 $ Stream.intervalsOf 1 Fold.sum $ Stream.constRate 2 $ Stream.enumerateFrom 1
1759+-- [...,...,...,...,...]
1760+--
17271761-- @since 0.7.0
17281762{-# INLINE intervalsOf #-}
17291763intervalsOf
@@ -2188,12 +2222,18 @@ classifyChunksOf wsize = classifyChunksBy wsize False
21882222-- @
21892223--
21902224-- @
2191−-- >>> S.mapM_ print
2192−-- $ S.classifySessionsOf 3 (const (return False)) (fmap Right FL.toList)
2193−-- $ S.map (\(ts,(k,a)) -> (k, a, ts))
2194−-- $ S.timestamped
2195−-- $ S.delay 1
2196−-- $ (,) <$> S.fromList [1,2,3] <*> S.fromList [1,2,3]
2225+-- > :{
2226+-- Stream.mapM_ print
2227+-- $ Stream.classifySessionsOf 3 (const (return False)) (fmap Right Fold.toList)
2228+-- $ Stream.map (\\(ts,(k,a)) -> (k, a, ts))
2229+-- $ Stream.timestamped
2230+-- $ Stream.delay 1
2231+-- $ (,) <$> Stream.fromList [1,2,3] <*> Stream.fromList [1,2,3]
2232+-- :}
2233+-- (1,Right [1,2,3])
2234+-- (2,Right [1,2,3])
2235+-- (3,Right [1,2,3])
2236+--
21972237-- @
21982238--
21992239-- /Internal/
src/Streamly/Internal/Data/Stream/IsStream/Top.hs+12−8
@@ -78,6 +78,12 @@ import qualified Streamly.Internal.Data.Stream.StreamK as StreamK
7878
7979import Prelude hiding (filter, zipWith, concatMap, concat)
8080
81+-- $setup
82+-- >>> :m
83+-- >>> import Prelude hiding (filter, zipWith, concatMap, concat)
84+-- >>> import qualified Streamly.Prelude as Stream
85+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
86+
8187------------------------------------------------------------------------------
8288-- Sampling
8389------------------------------------------------------------------------------
@@ -88,10 +94,8 @@ import Prelude hiding (filter, zipWith, concatMap, concat)
8894-- | @sampleFromthen offset stride@ samples the element at @offset@ index and
8995-- then every element at strides of @stride@.
9096--
91−-- @
9297-- >>> Stream.toList $ Stream.sampleFromThen 2 3 $ Stream.enumerateFromTo 0 10
93−-- [1,4,7,10]
94−-- @
98+-- [2,5,8]
9599--
96100-- /Internal/
97101--
@@ -468,15 +472,15 @@ mergeOuterJoin _eq _s1 _s2 = undefined
468472-- elements in the first stream that are present in the second stream.
469473--
470474-- >>> Stream.toList $ Stream.intersectBy (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [2,1,1,3])
471−-- > [1,2,2]
475+-- [1,2,2]
472476--
473477-- >>> Stream.toList $ Stream.intersectBy (==) (Stream.fromList [2,1,1,3]) (Stream.fromList [1,2,2,4])
474−-- > [2,1,1]
478+-- [2,1,1]
475479--
476480-- 'intersectBy' is similar to but not the same as 'innerJoin':
477481--
478482-- >>> Stream.toList $ fmap fst $ Stream.innerJoin (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [2,1,1,3])
479−-- > [1,1,2,2]
483+-- [1,1,2,2]
480484--
481485-- Space: O(n) where @n@ is the number of elements in the second stream.
482486--
@@ -513,7 +517,7 @@ mergeIntersectBy _eq _s1 _s2 = undefined
513517-- second stream as many occurrences of it are deleted from the first stream.
514518--
515519-- >>> Stream.toList $ Stream.differenceBy (==) (Stream.fromList [1,2,2]) (Stream.fromList [1,2,3])
516−-- > [2]
520+-- [2]
517521--
518522-- The following laws hold:
519523--
@@ -559,7 +563,7 @@ mergeDifferenceBy _eq _s1 _s2 = undefined
559563-- in the first stream.
560564--
561565-- >>> Stream.toList $ Stream.unionBy (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [1,1,2,3])
562−-- > [1,2,2,4,1,3]
566+-- [1,2,2,4,3]
563567--
564568-- Equivalent to the following except that @s1@ is evaluated only once:
565569--
src/Streamly/Internal/Data/Stream/IsStream/Transform.hs+56−68
@@ -260,6 +260,15 @@ import Prelude hiding
260260 ( filter, drop, dropWhile, take, takeWhile, foldr, map, mapM, sequence
261261 , reverse, foldr1 , scanl, scanl1)
262262
263+--
264+-- $setup
265+-- >>> :m
266+-- >>> import Prelude hiding ( filter, drop, dropWhile, take, takeWhile, foldr, map, mapM, sequence, reverse, foldr1 , scanl, scanl1)
267+-- >>> import qualified Streamly.Prelude as Stream
268+-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
269+-- >>> import qualified Streamly.Data.Fold as Fold
270+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
271+
263272------------------------------------------------------------------------------
264273-- Piping
265274------------------------------------------------------------------------------
@@ -285,18 +294,18 @@ transform pipe xs = fromStreamD $ D.transform pipe (toStreamD xs)
285294-- stateful transformations. However, note that the custom map and filter
286295-- routines can be much more efficient than this due to better stream fusion.
287296--
288−-- >>> S.toList $ S.foldrS S.cons S.nil $ S.fromList [1..5]
289−-- > [1,2,3,4,5]
297+-- >>> Stream.toList $ Stream.foldrS Stream.cons Stream.nil $ Stream.fromList [1..5]
298+-- [1,2,3,4,5]
290299--
291300-- Find if any element in the stream is 'True':
292301--
293−-- >>> 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)
294−-- > [True]
302+-- >>> Stream.toList $ Stream.foldrS (\x xs -> if odd x then return True else xs) (return False) $ (Stream.fromList (2:4:5:undefined) :: Stream.SerialT IO Int)
303+-- [True]
295304--
296305-- Map (+2) on odd elements and filter out the even elements:
297306--
298−-- >>> 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)
299−-- > [3,5,7]
307+-- >>> Stream.toList $ Stream.foldrS (\x xs -> if odd x then (x + 2) `Stream.cons` xs else xs) Stream.nil $ (Stream.fromList [1..5] :: Stream.SerialT IO Int)
308+-- [3,5,7]
300309--
301310-- 'foldrM' can also be represented in terms of 'foldrS', however, the former
302311-- is much more efficient:
@@ -400,11 +409,9 @@ sequence m = fromStreamS $ S.sequence (toStreamS m)
400409--
401410-- @
402411--
403−-- @
404−-- > S.drain $ S.tap (FL.drainBy print) (S.enumerateFromTo 1 2)
412+-- >>> Stream.drain $ Stream.tap (Fold.drainBy print) (Stream.enumerateFromTo 1 2)
405413-- 1
406414-- 2
407−-- @
408415--
409416-- Compare with 'trace'.
410417--
@@ -420,10 +427,9 @@ tap f xs = D.fromStreamD $ D.tap f (D.toStreamD xs)
420427-- means start at the first element in the stream. If the offset is outside
421428-- this range then @offset `mod` n@ is used as offset.
422429--
423−-- @
424−-- >>> S.drain $ S.tapOffsetEvery 0 2 (FL.rmapM print FL.toList) $ S.enumerateFromTo 0 10
425−-- > [0,2,4,6,8,10]
426−-- @
430+-- >>> Stream.drain $ Stream.tapOffsetEvery 0 2 (Fold.rmapM print Fold.toList) $ Stream.enumerateFromTo 0 10
431+-- [0,2,4,6,8,10]
432+
427433--
428434-- /Internal/
429435--
@@ -798,8 +804,10 @@ uniq = fromStreamD . D.uniq . toStreamD
798804-- prune p = dropWhileAround p $ uniqBy (x y -> p x && p y)
799805-- @
800806--
801−-- >>> Stream.pruneBy isSpace (Stream.fromList " hello world! ")
807+-- @
808+-- > Stream.pruneBy isSpace (Stream.fromList " hello world! ")
802809-- "hello world!"
810+-- @
803811--
804812-- Space: @O(1)@
805813--
@@ -1084,10 +1092,8 @@ insertBy cmp x m = fromStreamS $ S.insertBy cmp x (toStreamS m)
10841092
10851093-- | Insert a pure value between successive elements of a stream.
10861094--
1087−-- @
1088−-- > S.toList $ S.intersperse ',' $ S.fromList "hello"
1095+-- >>> Stream.toList $ Stream.intersperse ',' $ Stream.fromList "hello"
10891096-- "h,e,l,l,o"
1090−-- @
10911097--
10921098-- @since 0.7.0
10931099{-# INLINE intersperse #-}
@@ -1097,10 +1103,8 @@ intersperse a = fromStreamS . S.intersperse a . toStreamS
10971103-- | Insert a side effect before consuming an element of a stream except the
10981104-- first one.
10991105--
1100−-- @
1101−-- >>> S.drain $ S.trace putChar $ S.intersperseM_ (putChar '.') $ S.fromList "hello"
1102−-- > h.e.l.l.o
1103−-- @
1106+-- >>> Stream.drain $ Stream.trace putChar $ Stream.intersperseM_ (putChar '.') $ Stream.fromList "hello"
1107+-- h.e.l.l.o
11041108--
11051109-- /Internal/
11061110{-# INLINE intersperseM_ #-}
@@ -1123,10 +1127,8 @@ intersperseBySpan _n _f _xs = undefined
11231127
11241128-- | Insert an effect and its output after consuming an element of a stream.
11251129--
1126−-- @
1127−-- >>> S.toList $ S.trace putChar $ S.intersperseSuffix (putChar '.' >> return ',') $ S.fromList "hello"
1128−-- > h.,e.,l.,l.,o.,"h,e,l,l,o,"
1129−-- @
1130+-- >>> Stream.toList $ Stream.trace putChar $ intersperseSuffix (putChar '.' >> return ',') $ Stream.fromList "hello"
1131+-- h.,e.,l.,l.,o.,"h,e,l,l,o,"
11301132--
11311133-- /Internal/
11321134{-# INLINE intersperseSuffix #-}
@@ -1150,10 +1152,8 @@ intersperseSuffix_ m = fromStreamD . D.intersperseSuffix_ m . toStreamD
11501152-- | Like 'intersperseSuffix' but intersperses an effectful action into the
11511153-- input stream after every @n@ elements and after the last element.
11521154--
1153−-- @
1154−-- > S.toList $ S.intersperseSuffixBySpan 2 (return ',') $ S.fromList "hello"
1155+-- >>> Stream.toList $ Stream.intersperseSuffixBySpan 2 (return ',') $ Stream.fromList "hello"
11551156-- "he,ll,o,"
1156−-- @
11571157--
11581158-- /Internal/
11591159--
@@ -1165,10 +1165,8 @@ intersperseSuffixBySpan n eff =
11651165
11661166-- | Insert a side effect before consuming an element of a stream.
11671167--
1168−-- @
1169−-- >>> S.toList $ S.trace putChar $ S.interspersePrefix_ (putChar '.' >> return ',') $ S.fromList "hello"
1170−-- > .h.e.l.l.o"hello"
1171−-- @
1168+-- >>> Stream.toList $ Stream.trace putChar $ Stream.interspersePrefix_ (putChar '.' >> return ',') $ Stream.fromList "hello"
1169+-- .h.e.l.l.o"hello"
11721170--
11731171-- Same as 'trace_' but may be concurrent.
11741172--
@@ -1189,12 +1187,10 @@ interspersePrefix_ m = mapM (\x -> void m >> return x)
11891187-- | Introduce a delay of specified seconds before consuming an element of the
11901188-- stream except the first one.
11911189--
1192−-- @
1193−-- >>> S.mapM_ print $ S.timestamped $ S.delay 1 $ S.enumerateFromTo 1 3
1194−-- > (AbsTime (TimeSpec {sec = 2502706, nsec = 751137000}),1)
1195−-- > (AbsTime (TimeSpec {sec = 2502707, nsec = 743535000}),2)
1196−-- > (AbsTime (TimeSpec {sec = 2502708, nsec = 749758000}),3)
1197−-- @
1190+-- >>> Stream.mapM_ print $ Stream.timestamped $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1191+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1192+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1193+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
11981194--
11991195-- /Internal/
12001196--
@@ -1207,12 +1203,10 @@ delay n = intersperseM_ $ liftIO $ threadDelay $ round $ n * 1000000
12071203-- | Introduce a delay of specified seconds after consuming an element of a
12081204-- stream.
12091205--
1210−-- @
1211−-- >>> S.mapM_ print $ S.timestamped $ S.delayPost 1 $ S.enumerateFromTo 1 3
1212−-- > (AbsTime (TimeSpec {sec = 2502826, nsec = 119030000}),1)
1213−-- > (AbsTime (TimeSpec {sec = 2502827, nsec = 111393000}),2)
1214−-- > (AbsTime (TimeSpec {sec = 2502828, nsec = 112221000}),3)
1215−-- @
1206+-- >>> Stream.mapM_ print $ Stream.timestamped $ Stream.delayPost 1 $ Stream.enumerateFromTo 1 3
1207+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1208+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1209+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
12161210--
12171211-- /Internal/
12181212--
@@ -1225,12 +1219,10 @@ delayPost n = intersperseSuffix_ $ liftIO $ threadDelay $ round $ n * 1000000
12251219-- | Introduce a delay of specified seconds before consuming an element of a
12261220-- stream.
12271221--
1228−-- @
1229−-- >>> S.mapM_ print $ S.timestamped $ S.delayPre 1 $ S.enumerateFromTo 1 3
1230−-- > (AbsTime (TimeSpec {sec = 2502207, nsec = 533177000}),1)
1231−-- > (AbsTime (TimeSpec {sec = 2502208, nsec = 530859000}),2)
1232−-- > (AbsTime (TimeSpec {sec = 2502209, nsec = 531619000}),3)
1233−-- @
1222+-- >>> Stream.mapM_ print $ Stream.timestamped $ Stream.delayPre 1 $ Stream.enumerateFromTo 1 3
1223+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1224+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1225+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
12341226--
12351227-- /Internal/
12361228--
@@ -1267,10 +1259,8 @@ reassembleBy = undefined
12671259--
12681260-- Pair each element in a stream with its index, starting from index 0.
12691261--
1270−-- @
1271−-- > S.toList $ S.indexed $ S.fromList "hello"
1262+-- >>> Stream.toList $ Stream.indexed $ Stream.fromList "hello"
12721263-- [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
1273−-- @
12741264--
12751265-- @since 0.6.0
12761266{-# INLINE indexed #-}
@@ -1284,10 +1274,8 @@ indexed = fromStreamD . D.indexed . toStreamD
12841274-- Pair each element in a stream with its index, starting from the
12851275-- given index @n@ and counting down.
12861276--
1287−-- @
1288−-- > S.toList $ S.indexedR 10 $ S.fromList "hello"
1277+-- >>> Stream.toList $ Stream.indexedR 10 $ Stream.fromList "hello"
12891278-- [(10,'h'),(9,'e'),(8,'l'),(7,'l'),(6,'o')]
1290−-- @
12911279--
12921280-- @since 0.6.0
12931281{-# INLINE indexedR #-}
@@ -1309,9 +1297,10 @@ indexedR n = fromStreamD . D.indexedR n . toStreamD
13091297-- specified granularity. The timestamp is generated just before the element
13101298-- is consumed.
13111299--
1312−-- @
1313−-- >>> S.mapM_ print $ S.timestampWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
1314−-- @
1300+-- >>> Stream.mapM_ print $ Stream.timestampWith 0.01 $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1301+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1302+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1303+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
13151304--
13161305-- /Internal/
13171306--
@@ -1333,9 +1322,10 @@ timestamped = timestampWith 0.01
13331322-- clock with the specified granularity. The time is measured just before the
13341323-- element is consumed.
13351324--
1336−-- @
1337−-- >>> S.mapM_ print $ S.timeIndexWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
1338−-- @
1325+-- >>> Stream.mapM_ print $ Stream.timeIndexWith 0.01 $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1326+-- (RelTime64 (NanoSecond64 ...),1)
1327+-- (RelTime64 (NanoSecond64 ...),2)
1328+-- (RelTime64 (NanoSecond64 ...),3)
13391329--
13401330-- /Internal/
13411331--
@@ -1348,12 +1338,10 @@ timeIndexWith g stream = Z.zipWith (flip (,)) stream (relTimesWith g)
13481338-- 10 ms granularity clock. The time is measured just before the element is
13491339-- consumed.
13501340--
1351−-- @
1352−-- >>> S.mapM_ print $ S.timeIndexed $ S.delay 1 $ S.enumerateFromTo 1 3
1353−-- (RelTime64 (NanoSecond64 0),1)
1354−-- (RelTime64 (NanoSecond64 996239000),2)
1355−-- (RelTime64 (NanoSecond64 1996712000),3)
1356−-- @
1341+-- >>> Stream.mapM_ print $ Stream.timeIndexed $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1342+-- (RelTime64 (NanoSecond64 ...),1)
1343+-- (RelTime64 (NanoSecond64 ...),2)
1344+-- (RelTime64 (NanoSecond64 ...),3)
13571345--
13581346-- /Internal/
13591347--
src/Streamly/Internal/Data/Stream/Parallel.hs+28−13
@@ -72,6 +72,13 @@ import qualified Streamly.Internal.Data.Stream.SVar as SVar
7272
7373#include "Instances.hs"
7474
75+--
76+-- $setup
77+-- >>> :m
78+-- >>> import Prelude hiding (map)
79+-- >>> import qualified Streamly.Prelude as Stream
80+-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
81+
7582-------------------------------------------------------------------------------
7683-- Parallel
7784-------------------------------------------------------------------------------
@@ -228,27 +235,28 @@ infixr 6 `parallel`
228235-- singleton streams. The following trivial example is semantically equivalent
229236-- to running the action @putStrLn "hello"@ in the current thread:
230237--
231−-- >>> S.toList $ S.yieldM (putStrLn "hello") `parallel` S.nil
232−-- > hello
233−-- > [()]
238+-- >>> Stream.toList $ Stream.yieldM (putStrLn "hello") `Stream.parallel` Stream.nil
239+-- hello
240+-- [()]
234241--
235242-- Run two actions concurrently:
236243--
237−-- >>> S.toList $ S.yieldM (putStrLn "hello") `parallel` S.yieldM (putStrLn "world")
238−-- > hello
239−-- > world
240−-- > [(),()]
244+-- >>> import Control.Concurrent (threadDelay)
245+-- >>> Stream.toList $ Stream.yieldM (putStrLn "hello") `Stream.parallel` Stream.yieldM (threadDelay 100000 >> putStrLn "world")
246+-- hello
247+-- world
248+-- [(),()]
241249--
242250-- Run effects concurrently, disregarding their outputs:
243251--
244−-- >>> S.toList $ S.nilM (putStrLn "hello") `parallel` S.nilM (putStrLn "world")
245−-- > hello
246−-- > world
247−-- > []
252+-- >>> Stream.toList $ nilM (putStrLn "hello") `parallel` Stream.nilM (threadDelay 100000 >> putStrLn "world")
253+-- hello
254+-- world
255+-- []
248256--
249257-- Run an effectful action, and a pure effect without any output, concurrently:
250258--
251−-- >>> S.toList $ S.yieldM (return 1) `parallel` S.nilM (putStrLn "world")
259+-- >>> Stream.toList $ Stream.yieldM (return 1) `Stream.parallel` Stream.nilM (putStrLn "world")
252260-- world
253261-- [1]
254262--
@@ -449,7 +457,14 @@ tapAsyncF f (D.Stream step1 state1) = D.Stream step TapInit
449457-- | Concurrently distribute a stream to a collection of fold functions,
450458-- discarding the outputs of the folds.
451459--
452−-- >>> S.drain $ distributeAsync_ [S.mapM_ print, S.mapM_ print] (S.enumerateFromTo 1 2)
460+-- @
461+-- > Stream.drain $ Stream.distributeAsync_ [Stream.mapM_ print, Stream.mapM_ print] (Stream.enumerateFromTo 1 2)
462+-- 1
463+-- 2
464+-- 1
465+-- 2
466+--
467+-- @
453468--
454469-- @
455470-- distributeAsync_ = flip (foldr tapAsync)
src/Streamly/Internal/Data/Stream/StreamK.hs+4
@@ -202,6 +202,9 @@ import Streamly.Internal.Data.Stream.StreamK.Type
202202
203203import qualified Streamly.Internal.Data.Fold.Types as FL
204204
205+-- $setup
206+-- >>> :m
207+
205208-------------------------------------------------------------------------------
206209-- Deconstruction
207210-------------------------------------------------------------------------------
@@ -524,6 +527,7 @@ tailPartial m = mkStream $ \st yld sng stp ->
524527-- lazy value @x@ i.e. the same location in memory. Thus @x@ can be defined
525528-- in terms of itself, creating structures with cyclic references.
526529--
530+-- >>> import Data.Function (fix)
527531-- >>> f ~(a, b) = ([1, b], head a)
528532-- >>> fix f
529533-- ([1,1],1)
src/Streamly/Internal/Data/Unfold/Types.hs+6
@@ -35,6 +35,12 @@ import Streamly.Internal.Data.Stream.StreamD.Step (Step(..))
3535
3636import Prelude hiding (const, map, concat, concatMap, zipWith)
3737
38+-- $setup
39+-- >>> :m
40+-- >>> import qualified Streamly.Prelude as Stream
41+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
42+-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
43+
3844------------------------------------------------------------------------------
3945-- Monadic Unfolds
4046------------------------------------------------------------------------------
src/Streamly/Internal/Unicode/Array/Char.hs+12−5
@@ -26,12 +26,19 @@ import Streamly.Internal.Data.Stream.IsStream (IsStream)
2626import qualified Streamly.Internal.Unicode.Stream as S
2727import qualified Streamly.Data.Array.Foreign as A
2828
29+-- $setup
30+-- >>> :m
31+-- >>> :set -XOverloadedStrings
32+-- >>> import Prelude hiding (String, lines, words, unlines, unwords)
33+-- >>> import qualified Streamly.Prelude as Stream
34+-- >>> import qualified Streamly.Internal.Unicode.Array.Char as Unicode
35+
2936-- | Break a string up into a stream of strings at newline characters.
3037-- The resulting strings do not contain newlines.
3138--
3239-- > lines = S.lines A.write
3340--
34−-- >>> S.toList $ lines $ S.fromList "lines\nthis\nstring\n\n\n"
41+-- >>> Stream.toList $ Unicode.lines $ Stream.fromList "lines\nthis\nstring\n\n\n"
3542-- ["lines","this","string","",""]
3643--
3744{-# INLINE lines #-}
@@ -43,8 +50,8 @@ lines = S.lines A.write
4350--
4451-- > words = S.words A.write
4552--
46−-- >>> S.toList $ words $ S.fromList "A newline\nis considered white space?"
47−-- ["A", "newline", "is", "considered", "white", "space?"]
53+-- >>> Stream.toList $ Unicode.words $ Stream.fromList "A newline\nis considered white space?"
54+-- ["A","newline","is","considered","white","space?"]
4855--
4956{-# INLINE words #-}
5057words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
@@ -55,7 +62,7 @@ words = S.words A.write
5562--
5663-- 'unlines' is an inverse operation to 'lines'.
5764--
58−-- >>> S.toList $ unlines $ S.fromList ["lines", "this", "string"]
65+-- >>> Stream.toList $ Unicode.unlines $ Stream.fromList ["lines", "this", "string"]
5966-- "lines\nthis\nstring\n"
6067--
6168-- > unlines = S.unlines A.read
@@ -72,7 +79,7 @@ unlines = S.unlines A.read
7279--
7380-- 'unwords' is an inverse operation to 'words'.
7481--
75−-- >>> S.toList $ unwords $ S.fromList ["unwords", "this", "string"]
82+-- >>> Stream.toList $ Unicode.unwords $ Stream.fromList ["unwords", "this", "string"]
7683-- "unwords this string"
7784--
7885-- > unwords = S.unwords A.read
src/Streamly/Internal/Unicode/Array/Prim/Pinned.hs+12−6
@@ -26,13 +26,19 @@ import Streamly.Internal.Data.Array.Prim.Pinned (Array)
2626import qualified Streamly.Internal.Unicode.Stream as S
2727import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
2828
29+-- $setup
30+-- >>> :m
31+-- >>> :set -XOverloadedStrings
32+-- >>> import qualified Streamly.Prelude as Stream
33+-- >>> import qualified Streamly.Internal.Unicode.Array.Prim.Pinned as Unicode
34+
2935-- | Break a string up into a stream of strings at newline characters.
3036-- The resulting strings do not contain newlines.
3137--
3238-- > lines = S.lines A.write
3339--
34−-- >>> S.toList $ lines $ S.fromList "lines\nthis\nstring\n\n\n"
35−-- ["lines","this","string","",""]
40+-- >>> Stream.toList $ Unicode.lines $ Stream.fromList "lines\nthis\nstring\n\n\n"
41+-- [fromListN 5 "lines",fromListN 4 "this",fromListN 6 "string",fromListN 0 "",fromListN 0 ""]
3642--
3743{-# INLINE lines #-}
3844lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
@@ -43,8 +49,8 @@ lines = S.lines A.write
4349--
4450-- > words = S.words A.write
4551--
46−-- >>> S.toList $ words $ S.fromList "A newline\nis considered white space?"
47−-- ["A", "newline", "is", "considered", "white", "space?"]
52+-- >>> Stream.toList $ Unicode.words $ Stream.fromList "A newline\nis considered white space?"
53+-- [fromListN 1 "A",fromListN 7 "newline",fromListN 2 "is",fromListN 10 "considered",fromListN 5 "white",fromListN 6 "space?"]
4854--
4955{-# INLINE words #-}
5056words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
@@ -55,7 +61,7 @@ words = S.words A.write
5561--
5662-- 'unlines' is an inverse operation to 'lines'.
5763--
58−-- >>> S.toList $ unlines $ S.fromList ["lines", "this", "string"]
64+-- >>> Stream.toList $ Unicode.unlines $ Stream.fromList ["lines", "this", "string"]
5965-- "lines\nthis\nstring\n"
6066--
6167-- > unlines = S.unlines A.read
@@ -72,7 +78,7 @@ unlines = S.unlines A.read
7278--
7379-- 'unwords' is an inverse operation to 'words'.
7480--
75−-- >>> S.toList $ unwords $ S.fromList ["unwords", "this", "string"]
81+-- >>> Stream.toList $ Unicode.unwords $ Stream.fromList ["unwords", "this", "string"]
7682-- "unwords this string"
7783--
7884-- > unwords = S.unwords A.read
src/Streamly/Internal/Unicode/Stream.hs+11−4
@@ -94,6 +94,13 @@ import qualified Streamly.Internal.Data.Stream.StreamD as D
9494
9595import Prelude hiding (String, lines, words, unlines, unwords)
9696
97+-- $setup
98+-- >>> :m
99+-- >>> import Prelude hiding (String, lines, words, unlines, unwords)
100+-- >>> import qualified Streamly.Prelude as Stream
101+-- >>> import qualified Streamly.Data.Fold as Fold
102+-- >>> import Streamly.Internal.Unicode.Stream
103+
97104-------------------------------------------------------------------------------
98105-- Encoding/Decoding Unicode (UTF-8) Characters
99106-------------------------------------------------------------------------------
@@ -859,8 +866,8 @@ stripStart = S.dropWhile isSpace
859866-- | Fold each line of the stream using the supplied 'Fold'
860867-- and stream the result.
861868--
862−-- >>> S.toList $ lines FL.toList (S.fromList "lines\nthis\nstring\n\n\n")
863−-- ["lines", "this", "string", "", ""]
869+-- >>> Stream.toList $ lines Fold.toList (Stream.fromList "lines\nthis\nstring\n\n\n")
870+-- ["lines","this","string","",""]
864871--
865872-- > lines = S.splitOnSuffix (== '\n')
866873--
@@ -884,8 +891,8 @@ isSpace c
884891-- | Fold each word of the stream using the supplied 'Fold'
885892-- and stream the result.
886893--
887−-- >>> S.toList $ words FL.toList (S.fromList "fold these words")
888−-- ["fold", "these", "words"]
894+-- >>> Stream.toList $ words Fold.toList (Stream.fromList "fold these words")
895+-- ["fold","these","words"]
889896--
890897-- > words = S.wordsBy isSpace
891898--
src/Streamly/Prelude.hs+20−16
@@ -655,6 +655,10 @@ import Prelude
655655
656656import Streamly.Internal.Data.Stream.IsStream
657657
658+-- $setup
659+-- >>> :m
660+-- >>> import qualified Streamly.Prelude as Stream
661+-- >>> import qualified Streamly.Data.Fold as Fold
658662
659663-- $streamtypes
660664-- The basic stream type is 'Serial', it represents a sequence of IO actions,
@@ -964,9 +968,9 @@ import Streamly.Internal.Data.Stream.IsStream
964968-- The following two ways of folding are equivalent in functionality and
965969-- performance,
966970--
967−-- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
971+-- >>> Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
968972-- 5050
969−-- >>> S.sum (S.enumerateFromTo 1 100)
973+-- >>> Stream.sum (Stream.enumerateFromTo 1 100)
970974-- 5050
971975--
972976-- However, left folds cannot terminate early even if it does not need to
@@ -978,30 +982,30 @@ import Streamly.Internal.Data.Stream.IsStream
978982-- fold in parallel the performance is not impacted as we anyway have to
979983-- consume the whole stream due to the full fold.
980984--
981−-- >>> S.head (1 `S.cons` undefined)
985+-- >>> Stream.head (1 `Stream.cons` undefined)
986+-- Just 1
987+-- >>> Stream.fold Fold.head (1 `Stream.cons` undefined)
982988-- Just 1
983−-- >>> S.fold FL.head (1 `S.cons` undefined)
984−-- *** Exception: Prelude.undefined
985989--
986990-- However, we can wrap the fold in a scan to convert it into a lazy stream of
987991-- fold steps. We can then terminate the stream whenever we want. For example,
988992--
989−-- >>> S.toList $ S.take 1 $ S.scan FL.head (1 `S.cons` undefined)
993+-- >>> Stream.toList $ Stream.take 1 $ Stream.scan Fold.head (1 `Stream.cons` undefined)
990994-- [Nothing]
991995--
992996-- The following example extracts the input stream up to a point where the
993997-- running average of elements is no more than 10:
994998--
995−-- @
996−-- > S.toList
997−-- $ S.map (fromJust . fst)
998−-- $ S.takeWhile (\\(_,x) -> x <= 10)
999−-- $ S.postscan ((,) \<$> FL.last \<*> avg) (S.enumerateFromTo 1.0 100.0)
1000−-- @
1001−-- @
1002−-- [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
1003−-- @
1004−
999+-- >>> import Data.Maybe (fromJust)
1000+-- >>> let avg = (/) <$> Fold.sum <*> fmap fromIntegral Fold.length
1001+-- >>> :{
1002+-- Stream.toList
1003+-- $ Stream.map (fromJust . fst)
1004+-- $ Stream.takeWhile (\(_,x) -> x <= 10)
1005+-- $ Stream.postscan ((,) <$> Fold.last <*> avg) (Stream.enumerateFromTo 1.0 100.0)
1006+-- :}
1007+-- [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
1008+--
10051009-- $application
10061010--
10071011-- Stream processing functions can be composed in a chain using function