on master help sign in
Fix examples in code to work with doctest.
da906cePranay Sashank
src/Streamly/Data/Fold.hs+13−6
@@ -62,7 +62,7 @@ module Streamly.Data.Fold
62 -- A 'Fold' can be run over a stream using the 'Streamly.Prelude.fold'
62 -- A 'Fold' can be run over a stream using the 'Streamly.Prelude.fold'
63 -- combinator:
63 -- combinator:
64 --
64 --
65− -- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
65+ -- >>> Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
66 -- 5050
66 -- 5050
67
67
68 Fold -- (..)
68 Fold -- (..)
@@ -123,7 +123,7 @@ module Streamly.Data.Fold
123 -- Transformations can be applied either on the input side or on the output
123 -- Transformations can be applied either on the input side or on the output
124 -- side. The 'Functor' instance of a fold maps on the output of the fold:
124 -- side. The 'Functor' instance of a fold maps on the output of the fold:
125 --
125 --
126− -- >>> S.fold (fmap show FL.sum) (S.enumerateFromTo 1 100)
126+ -- >>> Stream.fold (fmap show Fold.sum) (Stream.enumerateFromTo 1 100)
127 -- "5050"
127 -- "5050"
128 --
128 --
129 -- Note: Output transformations are also known as covariant
129 -- Note: Output transformations are also known as covariant
@@ -199,16 +199,16 @@ module Streamly.Data.Fold
199 -- To compute the average of numbers in a stream without going through the
199 -- To compute the average of numbers in a stream without going through the
200 -- stream twice:
200 -- stream twice:
201 --
201 --
202− -- >>> let avg = (/) <$> FL.sum <*> fmap fromIntegral FL.length
202+ -- >>> let avg = (/) <$> Fold.sum <*> fmap fromIntegral Fold.length
203− -- >>> S.fold avg (S.enumerateFromTo 1.0 100.0)
203+ -- >>> Stream.fold avg (Stream.enumerateFromTo 1.0 100.0)
204 -- 50.5
204 -- 50.5
205 --
205 --
206 -- The 'Semigroup' and 'Monoid' instances of a distributing fold distribute
206 -- The 'Semigroup' and 'Monoid' instances of a distributing fold distribute
207 -- the input to both the folds and combines the outputs using Monoid or
207 -- the input to both the folds and combines the outputs using Monoid or
208 -- Semigroup instances of the output types:
208 -- Semigroup instances of the output types:
209 --
209 --
210− -- >>> import Data.Monoid (Sum)
210+ -- >>> import Data.Monoid (Sum(..))
211− -- >>> S.fold (FL.head <> FL.last) (fmap Sum $ S.enumerateFromTo 1.0 100.0)
211+ -- >>> Stream.fold (Fold.head <> Fold.last) (fmap Sum $ Stream.enumerateFromTo 1.0 100.0)
212 -- Just (Sum {getSum = 101.0})
212 -- Just (Sum {getSum = 101.0})
213 --
213 --
214 -- The 'Num', 'Floating', and 'Fractional' instances work in the same way.
214 -- The 'Num', 'Floating', and 'Fractional' instances work in the same way.
@@ -265,3 +265,10 @@ import Prelude
265 span, splitAt, break, mapM)
265 span, splitAt, break, mapM)
266
266
267import Streamly.Internal.Data.Fold
267import 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(..))
117import qualified Data.Foldable as F
117import qualified Data.Foldable as F
118#endif
118#endif
119
119
120+--
121+-- $setup
122+-- >>> :m
123+-- >>> import Prelude hiding (length, foldr, read, unlines, splitAt)
124+-- >>> import Streamly.Internal.Data.Array.Foreign as Array
125+
120-------------------------------------------------------------------------------
126-------------------------------------------------------------------------------
121-- Array Data Type
127-- Array Data Type
122-------------------------------------------------------------------------------
128-------------------------------------------------------------------------------
@@ -230,11 +236,12 @@ fromPtr n ptr = MA.unsafeInlineIO $ do
230-- characters that can be encoded in a byte i.e. characters or literal bytes in
236-- characters that can be encoded in a byte i.e. characters or literal bytes in
231-- the range from 0-255.
237-- the range from 0-255.
232--
238--
239+-- >>> import Data.Word (Word8)
233−-- >>> fromAddr# 5 "hello world!"#
240+-- >>> Array.fromAddr# 5 "hello world!"# :: Array Word8
234−-- > [104,101,108,108,111]
241+-- [104,101,108,108,111]
235--
242--
236−-- >>> fromAddr# 3 "\255\NUL\255"#
243+-- >>> Array.fromAddr# 3 "\255\NUL\255"# :: Array Word8
237−-- > [255,0,255]
244+-- [255,0,255]
238--
245--
239-- /See also: 'fromString#'/
246-- /See also: 'fromString#'/
240--
247--
@@ -262,11 +269,11 @@ fromAddr# n addr# = fromPtr n (castPtr $ Ptr addr#)
262-- of bytes terminated by a NUL byte (a 'CString') corresponding to the
269-- of bytes terminated by a NUL byte (a 'CString') corresponding to the
263-- given unicode string.
270-- given unicode string.
264--
271--
265−-- >>> fromCString# "hello world!"#
272+-- >>> Array.fromCString# "hello world!"#
266−-- > [104,101,108,108,111,32,119,111,114,108,100,33]
273+-- [104,101,108,108,111,32,119,111,114,108,100,33]
267--
274--
268−-- >>> fromCString# "\255\NUL\255"#
275+-- >>> Array.fromCString# "\255\NUL\255"#
269−-- > [255]
276+-- [255]
270--
277--
271-- /See also: 'fromAddr#'/
278-- /See also: 'fromAddr#'/
272--
279--
src/Streamly/Internal/Data/Fold.hs+56−44
@@ -254,6 +254,15 @@ import Prelude hiding
254 , span, splitAt, break, mapM, zip)
254 , span, splitAt, break, mapM, zip)
255import Streamly.Internal.Data.Fold.Types
255import Streamly.Internal.Data.Fold.Types
256
256
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+
257------------------------------------------------------------------------------
266------------------------------------------------------------------------------
258-- hoist
267-- hoist
259------------------------------------------------------------------------------
268------------------------------------------------------------------------------
@@ -327,7 +336,7 @@ mapM = rmapM
327-- >>> f x = if even x then Just x else Nothing
336-- >>> f x = if even x then Just x else Nothing
328-- >>> fld = Fold.mapMaybe f Fold.toList
337-- >>> fld = Fold.mapMaybe f Fold.toList
329-- >>> Stream.fold fld (Stream.enumerateFromTo 1 10)
338-- >>> Stream.fold fld (Stream.enumerateFromTo 1 10)
330−-- [2,4,6,8]
339+-- [2,4,6,8,10]
331--
340--
332-- /Internal/
341-- /Internal/
333{-# INLINE mapMaybe #-}
342{-# INLINE mapMaybe #-}
@@ -847,7 +856,7 @@ null = mkFold (\() _ -> Done False) (Partial ()) (const True)
847-- | Returns 'True' if any of the elements of a stream satisfies a predicate.
856-- | Returns 'True' if any of the elements of a stream satisfies a predicate.
848--
857--
849-- >>> Stream.fold (Fold.any (== 0)) $ Stream.fromList [1,0,1]
858-- >>> Stream.fold (Fold.any (== 0)) $ Stream.fromList [1,0,1]
850−-- > True
859+-- True
851--
860--
852-- @since 0.7.0
861-- @since 0.7.0
853{-# INLINE any #-}
862{-# INLINE any #-}
@@ -879,7 +888,7 @@ elem a = any (a ==)
879-- | Returns 'True' if all elements of a stream satisfy a predicate.
888-- | Returns 'True' if all elements of a stream satisfy a predicate.
880--
889--
881-- >>> Stream.fold (Fold.all (== 0)) $ Stream.fromList [1,0,1]
890-- >>> Stream.fold (Fold.all (== 0)) $ Stream.fromList [1,0,1]
882−-- > False
891+-- False
883--
892--
884-- @since 0.7.0
893-- @since 0.7.0
885{-# INLINABLE all #-}
894{-# INLINABLE all #-}
@@ -942,25 +951,25 @@ or = any (== True)
942-- elements of its input are consumed by fold @f1@ and the rest of the stream
951-- elements of its input are consumed by fold @f1@ and the rest of the stream
943-- is consumed by fold @f2@.
952-- is consumed by fold @f2@.
944--
953--
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
946--
955--
947-- >>> splitAt_ 6 "Hello World!"
956-- >>> splitAt_ 6 "Hello World!"
948−-- > ("Hello ","World!")
957+-- ("Hello ","World!")
949--
958--
950-- >>> splitAt_ (-1) [1,2,3]
959-- >>> splitAt_ (-1) [1,2,3]
951−-- > ([],[1,2,3])
960+-- ([],[1,2,3])
952--
961--
953-- >>> splitAt_ 0 [1,2,3]
962-- >>> splitAt_ 0 [1,2,3]
954−-- > ([],[1,2,3])
963+-- ([],[1,2,3])
955--
964--
956-- >>> splitAt_ 1 [1,2,3]
965-- >>> splitAt_ 1 [1,2,3]
957−-- > ([1],[2,3])
966+-- ([1],[2,3])
958--
967--
959-- >>> splitAt_ 3 [1,2,3]
968-- >>> splitAt_ 3 [1,2,3]
960−-- > ([1,2,3],[])
969+-- ([1,2,3],[])
961--
970--
962-- >>> splitAt_ 4 [1,2,3]
971-- >>> splitAt_ 4 [1,2,3]
963−-- > ([1,2,3],[])
972+-- ([1,2,3],[])
964--
973--
965-- > splitAt n f1 f2 = splitWith (,) (takeLE n f1) f2
974-- > splitAt n f1 f2 = splitWith (,) (takeLE n f1) f2
966--
975--
@@ -1009,9 +1018,9 @@ splitAt n fld = splitWith (,) (takeLE n fld)
1009--
1018--
1010-- Let's use the following definition for illustration:
1019-- Let's use the following definition for illustration:
1011--
1020--
1012−-- > splitOn p = Stream.foldMany (Fold.sliceSepBy pred Fold.toList)
1021+-- >>> splitOn p = Stream.foldMany (Fold.sliceSepBy pred Fold.toList)
1013−-- > splitOn' p = Stream.toList . splitOn p . Stream.fromList
1022+-- >>> splitOn' p = Stream.toList . splitOn p . Stream.fromList
1014−--
1023+
1015-- >>> splitOn' (== '.') ""
1024-- >>> splitOn' (== '.') ""
1016-- [""]
1025-- [""]
1017--
1026--
@@ -1019,16 +1028,16 @@ splitAt n fld = splitWith (,) (takeLE n fld)
1019-- ["",""]
1028-- ["",""]
1020--
1029--
1021-- >>> splitOn' (== '.') ".a"
1030-- >>> splitOn' (== '.') ".a"
1022−-- > ["","a"]
1031+-- ["","a"]
1023--
1032--
1024-- >>> splitOn' (== '.') "a."
1033-- >>> splitOn' (== '.') "a."
1025−-- > ["a",""]
1034+-- ["a",""]
1026--
1035--
1027-- >>> splitOn' (== '.') "a.b"
1036-- >>> splitOn' (== '.') "a.b"
1028−-- > ["a","b"]
1037+-- ["a","b"]
1029--
1038--
1030-- >>> splitOn' (== '.') "a..b"
1039-- >>> splitOn' (== '.') "a..b"
1031−-- > ["a","","b"]
1040+-- ["a","","b"]
1032--
1041--
1033-- Stops - when the predicate succeeds.
1042-- Stops - when the predicate succeeds.
1034--
1043--
@@ -1102,7 +1111,7 @@ breakOn pat f m = undefined
1102-- ---stream m a---| |---m (b,c)
1111-- ---stream m a---| |---m (b,c)
1103-- |-------Fold m a c--------|
1112-- |-------Fold m a c--------|
1104-- @
1113-- @
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)
1106-- (5050.0,100)
1115-- (5050.0,100)
1107--
1116--
1108-- @since 0.7.0
1117-- @since 0.7.0
@@ -1126,7 +1135,7 @@ tee = teeWith (,)
1126-- ...
1135-- ...
1127-- @
1136-- @
1128--
1137--
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)
1130-- [15,5]
1139-- [15,5]
1131--
1140--
1132-- This is the consumer side dual of the producer side 'sequence' operation.
1141-- This is the consumer side dual of the producer side 'sequence' operation.
@@ -1154,10 +1163,12 @@ distribute = foldr (teeWith (:)) (yield [])
1154--
1163--
1155-- Send input to either fold randomly:
1164-- Send input to either fold randomly:
1156--
1165--
1166+-- @
1157−-- >>> import System.Random (randomIO)
1167+-- > import System.Random (randomIO)
1158−-- >>> randomly a = randomIO >>= \x -> return $ if x then Left a else Right a
1168+-- > 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)
1169+-- > Stream.fold (Fold.partitionByM randomly Fold.length Fold.length) (Stream.enumerateFromTo 1 100)
1160-- (59,41)
1170-- (59,41)
1171+-- @
1161--
1172--
1162-- Send input to the two folds in a proportion of 2:1:
1173-- Send input to the two folds in a proportion of 2:1:
1163--
1174--
@@ -1279,13 +1290,13 @@ partitionByMinM = undefined
1279--
1290--
1280-- Count even and odd numbers in a stream:
1291-- Count even and odd numbers in a stream:
1281--
1292--
1282−-- @
1293+-- >>> :{
1283−-- >>> let f = FL.partitionBy (\\n -> if even n then Left n else Right n)
1294+-- let f = Fold.partitionBy (\n -> if even n then Left n else Right n)
1284−-- (fmap (("Even " ++) . show) FL.length)
1295+-- (fmap (("Even " ++) . show) Fold.length)
1285−-- (fmap (("Odd " ++) . show) FL.length)
1296+-- (fmap (("Odd " ++) . show) Fold.length)
1286−-- in S.fold f (S.enumerateFromTo 1 100)
1297+-- in Stream.fold f (Stream.enumerateFromTo 1 100)
1298+-- :}
1287-- ("Even 50","Odd 50")
1299-- ("Even 50","Odd 50")
1288−-- @
1289--
1300--
1290-- @since 0.7.0
1301-- @since 0.7.0
1291{-# INLINE partitionBy #-}
1302{-# INLINE partitionBy #-}
@@ -1355,12 +1366,13 @@ demuxWith f kv = fmap fst $ demuxDefaultWith f kv drain
1355-- key into a map from keys to the results of fold outputs of the corresponding
1366-- key into a map from keys to the results of fold outputs of the corresponding
1356-- values.
1367-- values.
1357--
1368--
1358−-- @
1369+-- >>> import qualified Data.Map
1370+-- >>> :{
1359−-- > let table = Data.Map.fromList [(\"SUM", FL.sum), (\"PRODUCT", FL.product)]
1371+-- let table = Data.Map.fromList [("SUM", Fold.sum), ("PRODUCT", Fold.product)]
1360−-- input = S.fromList [(\"SUM",1),(\"PRODUCT",2),(\"SUM",3),(\"PRODUCT",4)]
1372+-- input = Stream.fromList [("SUM",1),("PRODUCT",2),("SUM",3),("PRODUCT",4)]
1361−-- in S.fold (FL.demux table) input
1373+-- in Stream.fold (Fold.demux table) input
1374+-- :}
1362-- fromList [("PRODUCT",8),("SUM",4)]
1375-- fromList [("PRODUCT",8),("SUM",4)]
1363−-- @
1364--
1376--
1365-- @since 0.7.0
1377-- @since 0.7.0
1366{-# INLINE demux #-}
1378{-# INLINE demux #-}
@@ -1505,11 +1517,11 @@ demuxDefault = demuxDefaultWith id
1505-- given fold. Useful for map/reduce, bucketizing the input in different bins
1517-- given fold. Useful for map/reduce, bucketizing the input in different bins
1506-- or for generating histograms.
1518-- or for generating histograms.
1507--
1519--
1508−-- @
1520+-- >>> :{
1509−-- > let input = S.fromList [(\"ONE",1),(\"ONE",1.1),(\"TWO",2), (\"TWO",2.2)]
1521+-- let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
1510−-- in S.fold (FL.classify FL.toList) input
1522+-- in Stream.fold (Fold.classifyWith fst (Fold.map snd Fold.toList)) input
1523+-- :}
1511−-- fromList [(\"ONE",[1.1,1.0]),(\"TWO",[2.2,2.0])]
1524+-- fromList [("ONE",[1.0,1.1]),("TWO",[2.0,2.2])]
1512−-- @
1513--
1525--
1514-- If the classifier fold stops for a particular key any further inputs in that
1526-- If the classifier fold stops for a particular key any further inputs in that
1515-- bucket are ignored.
1527-- bucket are ignored.
@@ -1564,14 +1576,14 @@ classifyWith f (Fold step1 initial1 extract1) = mkAccumM step initial extract
1564-- the values belonging to each key. Useful for map/reduce, bucketizing the
1576-- the values belonging to each key. Useful for map/reduce, bucketizing the
1565-- input in different bins or for generating histograms.
1577-- input in different bins or for generating histograms.
1566--
1578--
1567−-- @
1579+-- >>> :{
1568−-- > let input = S.fromList [(\"ONE",1),(\"ONE",1.1),(\"TWO",2), (\"TWO",2.2)]
1580+-- let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
1569−-- in S.fold (FL.classify FL.toList) input
1581+-- in Stream.fold (Fold.classify Fold.toList) input
1582+-- :}
1570−-- fromList [(\"ONE",[1.1,1.0]),(\"TWO",[2.2,2.0])]
1583+-- fromList [("ONE",[1.0,1.1]),("TWO",[2.0,2.2])]
1571−-- @
1572--
1584--
1573-- @since 0.7.0
1585-- @since 0.7.0
1574−
1586+--
1575-- Same as:
1587-- Same as:
1576--
1588--
1577-- > classify fld = classifyWith fst (map snd fld)
1589-- > 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)
247
247
248import Prelude hiding (concatMap, filter, map)
248import Prelude hiding (concatMap, filter, map)
249
249
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+
250------------------------------------------------------------------------------
257------------------------------------------------------------------------------
251-- Monadic left folds
258-- Monadic left folds
252------------------------------------------------------------------------------
259------------------------------------------------------------------------------
@@ -693,7 +700,8 @@ data ConcatMapState m sa a c
693--
700--
694-- Compare with 'Monad' instance method '>>='.
701-- Compare with 'Monad' instance method '>>='.
695--
702--
703+-- >>> import Data.Maybe (fromJust)
696−-- >>> Stream.fold (concatMap (flip Fold.takeLE Fold.sum) (Fold.rmapM (return . fromJust) Fold.head)) $ Stream.fromList [10,9..1]
704+-- >>> Stream.fold (Fold.concatMap (flip Fold.takeLE Fold.sum) (Fold.rmapM (return . fromJust) Fold.head)) $ Stream.fromList [10,9..1]
697-- 45
705-- 45
698--
706--
699-- /Internal/
707-- /Internal/
@@ -848,7 +856,7 @@ instance (Monad m, Floating b) => Floating (Fold m a b) where
848
856
849-- | @(map f fold)@ maps the function @f@ on the input of the fold.
857-- | @(map f fold)@ maps the function @f@ on the input of the fold.
850--
858--
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)
852-- 338350
860-- 338350
853--
861--
854-- __Note__: This is not the same as 'fmap'. @map@ is contravariant where as
862-- __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
876
884
877-- | Include only those elements that pass a predicate.
885-- | Include only those elements that pass a predicate.
878--
886--
879−-- >>> S.fold (filter (> 5) FL.sum) [1..10]
887+-- >>> Stream.fold (Fold.filter (> 5) Fold.sum) $ Stream.fromList [1..10]
880-- 40
888-- 40
881--
889--
890+-- >>> Stream.fold (Fold.filter (< 5) Fold.sum) $ Stream.fromList [1..10]
891+-- 10
892+--
882-- @since 0.7.0
893-- @since 0.7.0
883{-# INLINABLE filter #-}
894{-# INLINABLE filter #-}
884filter :: Monad m => (a -> Bool) -> Fold m a r -> Fold m a r
895filter :: 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
206import qualified Streamly.Internal.Data.Parser.ParserD as D
206import qualified Streamly.Internal.Data.Parser.ParserD as D
207import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
207import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
208
208
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+
209-------------------------------------------------------------------------------
218-------------------------------------------------------------------------------
210-- Upgrade folds to parses
219-- Upgrade folds to parses
211-------------------------------------------------------------------------------
220-------------------------------------------------------------------------------
@@ -276,7 +285,7 @@ dieM = K.toParserK . D.dieM
276-- | Peek the head element of a stream, without consuming it. Fails if it
285-- | Peek the head element of a stream, without consuming it. Fails if it
277-- encounters end of input.
286-- encounters end of input.
278--
287--
279−-- >>> S.parse ((,) <$> PR.peek <*> PR.satisfy (> 0)) $ S.fromList [1]
288+-- >>> Stream.parse ((,) <$> Parser.peek <*> Parser.satisfy (> 0)) $ Stream.fromList [1]
280-- (1,1)
289-- (1,1)
281--
290--
282-- @
291-- @
@@ -291,8 +300,8 @@ peek = K.toParserK D.peek
291
300
292-- | Succeeds if we are at the end of input, fails otherwise.
301-- | Succeeds if we are at the end of input, fails otherwise.
293--
302--
294−-- >>> S.parse ((,) <$> PR.satisfy (> 0) <*> PR.eof) $ S.fromList [1]
303+-- >>> Stream.parse ((,) <$> Parser.satisfy (> 0) <*> Parser.eof) $ Stream.fromList [1]
295−-- > (1,())
304+-- (1,())
296--
305--
297-- /Internal/
306-- /Internal/
298--
307--
@@ -302,8 +311,8 @@ eof = K.toParserK D.eof
302
311
303-- | Returns the next element if it passes the predicate, fails otherwise.
312-- | Returns the next element if it passes the predicate, fails otherwise.
304--
313--
305−-- >>> S.parse (PR.satisfy (== 1)) $ S.fromList [1,0,1]
314+-- >>> Stream.parse (Parser.satisfy (== 1)) $ Stream.fromList [1,0,1]
306−-- > 1
315+-- 1
307--
316--
308-- /Internal/
317-- /Internal/
309--
318--
@@ -344,24 +353,27 @@ either = K.toParserK . D.either
344-- Examples: -
353-- Examples: -
345--
354--
346-- @
355-- @
356+-- >>> :{
347−-- takeBetween' low high ls = S.parse prsr (S.fromList ls)
357+-- takeBetween' low high ls = Stream.parse prsr (Stream.fromList ls)
348−-- where prsr = P.takeBetween low high FL.toList
358+-- where prsr = Parser.takeBetween low high Fold.toList
359+-- :}
360+--
349-- @
361-- @
350--
362--
351-- >>> takeBetween' 2 4 [1, 2, 3, 4, 5]
363-- >>> takeBetween' 2 4 [1, 2, 3, 4, 5]
352−-- > [1,2,3,4]
364+-- [1,2,3,4]
353--
365--
354-- >>> takeBetween' 2 4 [1, 2]
366-- >>> takeBetween' 2 4 [1, 2]
355−-- > [1,2]
367+-- [1,2]
356--
368--
357-- >>> takeBetween' 2 4 [1]
369-- >>> takeBetween' 2 4 [1]
358−-- > ParseError "takeBetween: Expecting alteast 2 elements, got 1"
370+-- *** Exception: ParseError "takeBetween: Expecting alteast 2 elements, got 1"
359--
371--
360-- >>> takeBetween' 0 0 [1, 2]
372-- >>> takeBetween' 0 0 [1, 2]
361−-- > []
373+-- []
362--
374--
363-- >>> takeBetween' 0 1 []
375-- >>> takeBetween' 0 1 []
364−-- > []
376+-- []
365--
377--
366-- @takeBetween@ is the most general take operation, other take operations can
378-- @takeBetween@ is the most general take operation, other take operations can
367-- be defined in terms of takeBetween. For example:
379-- be defined in terms of takeBetween. For example:
@@ -386,8 +398,8 @@ takeBetween m n = K.toParserK . D.takeBetween m n
386-- * Fails - if the stream or the collecting fold ends before it can collect
398-- * Fails - if the stream or the collecting fold ends before it can collect
387-- exactly @n@ elements.
399-- exactly @n@ elements.
388--
400--
389−-- >>> S.parse (PR.takeEQ 4 FL.toList) $ S.fromList [1,0,1]
401+-- >>> Stream.parse (Parser.takeEQ 4 Fold.toList) $ Stream.fromList [1,0,1]
390−-- > "takeEQ: Expecting exactly 4 elements, got 3"
402+-- *** Exception: ParseError "takeEQ: Expecting exactly 4 elements, input terminated on 3"
391--
403--
392-- /Internal/
404-- /Internal/
393--
405--
@@ -401,11 +413,11 @@ takeEQ n = K.toParserK . D.takeEQ n
401-- * Fails - if the stream or the collecting fold ends before producing @n@
413-- * Fails - if the stream or the collecting fold ends before producing @n@
402-- elements.
414-- elements.
403--
415--
404−-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
416+-- >>> Stream.parse (Parser.takeGE 4 Fold.toList) $ Stream.fromList [1,0,1]
405−-- > "takeGE: Expecting at least 4 elements, got only 3"
417+-- *** Exception: ParseError "takeGE: Expecting at least 4 elements, input terminated on 3"
406--
418--
407−-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1,0,1]
419+-- >>> Stream.parse (Parser.takeGE 4 Fold.toList) $ Stream.fromList [1,0,1,0,1]
408−-- > [1,0,1,0,1]
420+-- [1,0,1,0,1]
409--
421--
410-- /Internal/
422-- /Internal/
411--
423--
@@ -443,8 +455,8 @@ takeWhileP _cond = undefined -- K.toParserK . D.takeWhileP cond
443-- * Stops - when the predicate fails or the collecting fold stops.
455-- * Stops - when the predicate fails or the collecting fold stops.
444-- * Fails - never.
456-- * Fails - never.
445--
457--
446−-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
458+-- >>> Stream.parse (Parser.takeWhile (== 0) Fold.toList) $ Stream.fromList [0,0,1,0,1]
447−-- > [0,0]
459+-- [0,0]
448--
460--
449-- We can implement a @breakOn@ using 'takeWhile':
461-- We can implement a @breakOn@ using 'takeWhile':
450--
462--
@@ -518,22 +530,24 @@ sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond
518--
530--
519-- Examples: -
531-- Examples: -
520--
532--
521−-- @
533+-- >>> :{
522−-- sliceBeginWithOdd ls = S.parse prsr (S.fromList ls)
534+-- sliceBeginWithOdd ls = Stream.parse prsr (Stream.fromList ls)
523−-- where prsr = P.sliceBeginWith odd FL.toList
535+-- where prsr = Parser.sliceBeginWith odd Fold.toList
524−-- @
536+-- :}
537+--
525--
538--
526-- >>> sliceBeginWithOdd [2, 4, 6, 3]
539-- >>> sliceBeginWithOdd [2, 4, 6, 3]
527−-- > [2,4,6]
540+-- *** Exception: sliceBeginWith : slice begins with an element which fails the predicate
541+-- ...
528--
542--
529-- >>> sliceBeginWithOdd [3, 5, 7, 4]
543-- >>> sliceBeginWithOdd [3, 5, 7, 4]
530−-- > [3]
544+-- [3]
531--
545--
532-- >>> sliceBeginWithOdd [3, 4, 6, 8, 5]
546-- >>> sliceBeginWithOdd [3, 4, 6, 8, 5]
533−-- > [3,4,6,8]
547+-- [3,4,6,8]
534--
548--
535-- >>> sliceBeginWithOdd []
549-- >>> sliceBeginWithOdd []
536−-- > []
550+-- []
537--
551--
538-- /Internal/
552-- /Internal/
539--
553--
@@ -560,17 +574,20 @@ escapedSliceSepBy _cond _esc = undefined
560--
574--
561-- For example,
575-- For example,
562--
576--
577+-- @
563−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello}"
578+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello}"
564−-- > "hello"
579+-- "hello"
580+--
581+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello {world}}"
582+-- "hello world"
565--
583--
566−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello {world}}"
584+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello \\{world\\}}"
567−-- > "hello world"
585+-- "hello {world}"
568--
586--
569−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello \\{world\\}}"
587+-- > Stream.parse (Parser.escapedFrameBy (== '{') (== '}') (== '\\') Fold.toList) $ Stream.fromList "{hello {world}"
570−-- > "hello {world}"
588+-- ParseError "Unterminated '{'"
571--
589--
572−-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello {world}"
590+-- @
573−-- > ParseError "Unterminated '{'"
574--
591--
575-- /Unimplemented/
592-- /Unimplemented/
576{-# INLINABLE escapedFrameBy #-}
593{-# INLINABLE escapedFrameBy #-}
@@ -605,10 +622,12 @@ wordBy f = K.toParserK . D.wordBy f
605-- * Stops - when the comparison fails.
622-- * Stops - when the comparison fails.
606-- * Fails - never.
623-- * Fails - never.
607--
624--
625+-- >>> :{
608−-- > runGroupsBy eq =
626+-- runGroupsBy eq =
609−-- > Stream.toList
627+-- Stream.toList
610−-- > . Stream.parseMany (groupBy eq Fold.toList)
628+-- . Stream.parseMany (Parser.groupBy eq Fold.toList)
611−-- > . Stream.fromList
629+-- . Stream.fromList
630+-- :}
612--
631--
613-- >>> runGroupsBy (<) []
632-- >>> runGroupsBy (<) []
614-- []
633-- []
@@ -617,7 +636,7 @@ wordBy f = K.toParserK . D.wordBy f
617-- [[1]]
636-- [[1]]
618--
637--
619-- >>> runGroupsBy (<) [3, 5, 4, 1, 2, 0]
638-- >>> runGroupsBy (<) [3, 5, 4, 1, 2, 0]
620−-- [[3, 5, 4], [1, 2], [0]]
639+-- [[3,5,4],[1,2],[0]]
621--
640--
622-- /Internal/
641-- /Internal/
623--
642--
@@ -637,10 +656,12 @@ groupBy eq = K.toParserK . D.groupBy eq
637-- * Stops - when the comparison fails.
656-- * Stops - when the comparison fails.
638-- * Fails - never.
657-- * Fails - never.
639--
658--
659+-- >>> :{
640−-- > runGroupsByRolling eq =
660+-- runGroupsByRolling eq =
641−-- > Stream.toList
661+-- Stream.toList
642−-- > . Stream.parseMany (groupByRolling eq Fold.toList)
662+-- . Stream.parseMany (Parser.groupByRolling eq Fold.toList)
643−-- > . Stream.fromList
663+-- . Stream.fromList
664+-- :}
644--
665--
645-- >>> runGroupsByRolling (<) []
666-- >>> runGroupsByRolling (<) []
646-- []
667-- []
@@ -649,7 +670,7 @@ groupBy eq = K.toParserK . D.groupBy eq
649-- [[1]]
670-- [[1]]
650--
671--
651-- >>> runGroupsByRolling (<) [3, 5, 4, 1, 2, 0]
672-- >>> runGroupsByRolling (<) [3, 5, 4, 1, 2, 0]
652−-- [[3, 5], [4], [1, 2], [0]]
673+-- [[3,5],[4],[1,2],[0]]
653--
674--
654-- /Internal/
675-- /Internal/
655--
676--
@@ -659,10 +680,10 @@ groupByRolling eq = K.toParserK . D.groupByRolling eq
659
680
660-- | Match the given sequence of elements using the given comparison function.
681-- | Match the given sequence of elements using the given comparison function.
661--
682--
662−-- >>> S.parse $ S.eqBy (==) "string" $ S.fromList "string"
683+-- >>> Stream.parse (Parser.eqBy (==) "string") $ Stream.fromList "string"
663--
684--
664−-- >>> S.parse $ S.eqBy (==) "mismatch" $ S.fromList "match"
685+-- >>> Stream.parse (Parser.eqBy (==) "mismatch") $ Stream.fromList "match"
665−-- > *** Exception: ParseError "eqBy: failed, yet to match 7 elements"
686+-- *** Exception: ParseError "eqBy: failed, yet to match 7 elements"
666--
687--
667-- /Internal/
688-- /Internal/
668--
689--
@@ -687,7 +708,9 @@ eqBy cmp = K.toParserK . D.eqBy cmp
687-- This implementation is strict in the second argument, therefore, the
708-- This implementation is strict in the second argument, therefore, the
688-- following will fail:
709-- following will fail:
689--
710--
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+-- ...
691--
714--
692-- Compare with 'Applicative' instance method '<*>'. This implementation allows
715-- Compare with 'Applicative' instance method '<*>'. This implementation allows
693-- stream fusion but has quadratic complexity. This can fuse with other
716-- stream fusion but has quadratic complexity. This can fuse with other
@@ -729,7 +752,9 @@ splitWith f p1 p2 =
729-- This implementation is strict in the second argument, therefore, the
752-- This implementation is strict in the second argument, therefore, the
730-- following will fail:
753-- following will fail:
731--
754--
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+-- ...
733--
758--
734-- Compare with 'Applicative' instance method '*>'. This implementation allows
759-- Compare with 'Applicative' instance method '*>'. This implementation allows
735-- stream fusion but has quadratic complexity. This can fuse with other
760-- stream fusion but has quadratic complexity. This can fuse with other
@@ -783,7 +808,8 @@ teeWithMin f p1 p2 =
783-- Note: This implementation is not lazy in the second argument. The following
808-- Note: This implementation is not lazy in the second argument. The following
784-- will fail:
809-- will fail:
785--
810--
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
787--
813--
788-- Compare with 'Alternative' instance method '<|>'. This implementation allows
814-- Compare with 'Alternative' instance method '<|>'. This implementation allows
789-- stream fusion but has quadratic complexity. This can fuse with other
815-- 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
172import Streamly.Internal.Data.Parser.ParserD.Tee
172import Streamly.Internal.Data.Parser.ParserD.Tee
173import Streamly.Internal.Data.Parser.ParserD.Types
173import Streamly.Internal.Data.Parser.ParserD.Types
174
174
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+
175-------------------------------------------------------------------------------
184-------------------------------------------------------------------------------
176-- Upgrade folds to parses
185-- Upgrade folds to parses
177-------------------------------------------------------------------------------
186-------------------------------------------------------------------------------
@@ -571,7 +580,7 @@ sliceBeginWith cond (Fold fstep finitial fextract) =
571 step (Left' s) a =
580 step (Left' s) a =
572 if cond a
581 if cond a
573 then process s a
582 then process s a
574− else error $ "sliceBeginWith : slice begins with an element which"
583+ else error $ "sliceBeginWith : slice begins with an element which "
575 ++ "fails the predicate"
584 ++ "fails the predicate"
576 step (Right' s) a =
585 step (Right' s) a =
577 if not (cond a)
586 if not (cond a)
@@ -739,16 +748,19 @@ eqBy cmp str = Parser step initial extract
739-- input as long as the predicate @p@ is 'True'. @f2@ consumes the rest of the
748-- input as long as the predicate @p@ is 'True'. @f2@ consumes the rest of the
740-- input.
749-- input.
741--
750--
751+-- @
742−-- > let span_ p xs = S.parse (FL.span p FL.toList FL.toList) $ S.fromList xs
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])
743--
756--
744−-- >>> span_ (< 1) [1,2,3]
757+-- > span_ (< 2) [1,2,3]
745−-- > ([],[1,2,3])
758+-- ([1],[2,3])
746--
759--
747−-- >>> span_ (< 2) [1,2,3]
760+-- > span_ (< 4) [1,2,3]
748−-- > ([1],[2,3])
761+-- ([1,2,3],[])
749--
762--
750−-- >>> span_ (< 4) [1,2,3]
763+-- @
751−-- > ([1,2,3],[])
752--
764--
753-- /Internal/
765-- /Internal/
754{-# INLINE span #-}
766{-# INLINE span #-}
src/Streamly/Internal/Data/Parser/ParserD/Types.hs+10−1
@@ -142,6 +142,14 @@ import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
142import qualified Streamly.Internal.Data.Fold.Types as FL
142import qualified Streamly.Internal.Data.Fold.Types as FL
143
143
144import Prelude hiding (concatMap)
144import 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
145
153
146-- | The return type of a 'Parser' step.
154-- | The return type of a 'Parser' step.
147--
155--
@@ -634,7 +642,8 @@ dieM err =
634-- Note: The implementation of '<|>' is not lazy in the second
642-- Note: The implementation of '<|>' is not lazy in the second
635-- argument. The following code will fail:
643-- argument. The following code will fail:
636--
644--
637−-- >>> S.parse (PR.satisfy (> 0) <|> undefined) $ S.fromList [1..10]
645+-- >>> Stream.parse (Parser.satisfy (> 0) <|> undefined) $ Stream.fromList [1..10]
646+-- 1
638--
647--
639instance MonadCatch m => Alternative (Parser m a) where
648instance MonadCatch m => Alternative (Parser m a) where
640 {-# INLINE empty #-}
649 {-# 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
74
74
75import Prelude hiding (take, takeWhile, drop, reverse)
75import Prelude hiding (take, takeWhile, drop, reverse)
76
76
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+
77------------------------------------------------------------------------------
86------------------------------------------------------------------------------
78-- Generation
87-- Generation
79------------------------------------------------------------------------------
88------------------------------------------------------------------------------
@@ -112,7 +121,7 @@ yield = K.yield
112-- Create a singleton stream from a monadic action.
121-- Create a singleton stream from a monadic action.
113--
122--
114-- @
123-- @
115−-- > toList $ yieldM getLine
124+-- > Stream.toList $ Stream.yieldM getLine
116-- hello
125-- hello
117-- ["hello"]
126-- ["hello"]
118-- @
127-- @
@@ -159,12 +168,12 @@ repeatMSerial = fromStreamS . S.repeatM
159-- A lower granularity clock gives higher precision but is more expensive in
168-- A lower granularity clock gives higher precision but is more expensive in
160-- terms of CPU usage. Any granularity lower than 1 ms is treated as 1 ms.
169-- terms of CPU usage. Any granularity lower than 1 ms is treated as 1 ms.
161--
170--
162−-- @
171+-- >>> import Control.Concurrent (threadDelay)
172+-- >>> import Streamly.Internal.Data.Stream.IsStream.Common as Stream (timesWith)
163−-- >>> S.mapM_ (\x -> print x >> threadDelay 1000000) $ S.timesWith 0.01
173+-- >>> Stream.mapM_ (\x -> print x >> threadDelay 1000000) $ Stream.take 3 $ Stream.timesWith 0.01
164−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 0))
174+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
165−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1002028000))
175+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
166−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1996656000))
176+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
167−-- @
168--
177--
169-- Note: This API is not safe on 32-bit machines.
178-- Note: This API is not safe on 32-bit machines.
170--
179--
@@ -179,9 +188,10 @@ timesWith g = fromStreamD $ D.times g
179-- expensive in terms of CPU usage. Any granularity lower than 1 ms is treated
188-- expensive in terms of CPU usage. Any granularity lower than 1 ms is treated
180-- as 1 ms.
189-- as 1 ms.
181--
190--
182−-- @
183−-- >>> S.mapM_ print $ S.delayPre 1 $ S.absTimesWith 0.01
191+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ absTimesWith 0.01
184−-- @
192+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
193+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
194+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
185--
195--
186-- Note: This API is not safe on 32-bit machines.
196-- Note: This API is not safe on 32-bit machines.
187--
197--
@@ -197,12 +207,10 @@ absTimesWith = fmap (uncurry addToAbsTime64) . timesWith
197-- clock is more expensive in terms of CPU usage. Any granularity lower than 1
207-- clock is more expensive in terms of CPU usage. Any granularity lower than 1
198-- ms is treated as 1 ms.
208-- ms is treated as 1 ms.
199--
209--
200−-- @
201−-- >>> S.mapM_ print $ S.delayPre 1 $ S.relTimesWith 0.01
210+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimesWith 0.01
202−-- > RelTime64 (NanoSecond64 0)
211+-- RelTime64 (NanoSecond64 ...)
203−-- > RelTime64 (NanoSecond64 91139000)
212+-- RelTime64 (NanoSecond64 ...)
204−-- > RelTime64 (NanoSecond64 204052000)
213+-- RelTime64 (NanoSecond64 ...)
205−-- @
206--
214--
207-- Note: This API is not safe on 32-bit machines.
215-- Note: This API is not safe on 32-bit machines.
208--
216--
@@ -222,7 +230,7 @@ relTimesWith = fmap snd . timesWith
222-- 'Fold' can terminate early without consuming the full stream. See the
230-- 'Fold' can terminate early without consuming the full stream. See the
223-- documentation of individual 'Fold's for termination behavior.
231-- documentation of individual 'Fold's for termination behavior.
224--
232--
225−-- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
233+-- >>> Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
226-- 5050
234-- 5050
227--
235--
228-- @fold f = parse (Parser.fromFold f)@
236-- @fold f = parse (Parser.fromFold f)@
@@ -368,10 +376,8 @@ findIndices p m = fromStreamS $ S.findIndices p (toStreamS m)
368-- | Insert an effect and its output before consuming an element of a stream
376-- | Insert an effect and its output before consuming an element of a stream
369-- except the first one.
377-- except the first one.
370--
378--
371−-- @
372−-- >>> S.toList $ S.trace putChar $ S.intersperseM (putChar '.' >> return ',') $ S.fromList "hello"
379+-- >>> Stream.toList $ Stream.trace putChar $ Stream.intersperseM (putChar '.' >> return ',') $ Stream.fromList "hello"
373−-- > h.,e.,l.,l.,o"h,e,l,l,o"
380+-- h.,e.,l.,l.,o"h,e,l,l,o"
374−-- @
375--
381--
376-- @since 0.5.0
382-- @since 0.5.0
377{-# INLINE intersperseM #-}
383{-# INLINE intersperseM #-}
@@ -382,8 +388,9 @@ intersperseM m = fromStreamS . S.intersperseM m . toStreamS
382-- seconds.
388-- seconds.
383--
389--
384-- @
390-- @
391+-- > import Control.Concurrent (threadDelay)
385−-- > S.drain $ S.interjectSuffix 1 (putChar ',') $ S.mapM (\\x -> threadDelay 1000000 >> putChar x) $ S.fromList "hello"
392+-- > Stream.drain $ Stream.interjectSuffix 1 (putChar ',') $ Stream.mapM (\x -> threadDelay 1000000 >> putChar x) $ Stream.fromList "hello"
386−-- "h,e,l,l,o"
393+-- h,e,l,l,o
387-- @
394-- @
388--
395--
389-- /Internal/
396-- /Internal/
@@ -463,36 +470,34 @@ concatM generator = concatMapM (\() -> generator) (yield ())
463--
470--
464-- For illustration, let's define a function that operates on pure lists:
471-- For illustration, let's define a function that operates on pure lists:
465--
472--
466−-- @
467−-- splitOnSeq' pat xs = S.toList $ S.splitOnSeq (A.fromList pat) (FL.toList) (S.fromList xs)
473+-- >>> splitOnSeq' pat xs = Stream.toList $ Stream.splitOnSeq (Array.fromList pat) Fold.toList (Stream.fromList xs)
468−-- @
469--
474--
470-- >>> splitOnSeq' "" "hello"
475-- >>> splitOnSeq' "" "hello"
471−-- > ["h","e","l","l","o"]
476+-- ["h","e","l","l","o"]
472--
477--
473-- >>> splitOnSeq' "hello" ""
478-- >>> splitOnSeq' "hello" ""
474−-- > [""]
479+-- [""]
475--
480--
476-- >>> splitOnSeq' "hello" "hello"
481-- >>> splitOnSeq' "hello" "hello"
477−-- > ["",""]
482+-- ["",""]
478--
483--
479-- >>> splitOnSeq' "x" "hello"
484-- >>> splitOnSeq' "x" "hello"
480−-- > ["hello"]
485+-- ["hello"]
481--
486--
482-- >>> splitOnSeq' "h" "hello"
487-- >>> splitOnSeq' "h" "hello"
483−-- > ["","ello"]
488+-- ["","ello"]
484--
489--
485-- >>> splitOnSeq' "o" "hello"
490-- >>> splitOnSeq' "o" "hello"
486−-- > ["hell",""]
491+-- ["hell",""]
487--
492--
488-- >>> splitOnSeq' "e" "hello"
493-- >>> splitOnSeq' "e" "hello"
489−-- > ["h","llo"]
494+-- ["h","llo"]
490--
495--
491-- >>> splitOnSeq' "l" "hello"
496-- >>> splitOnSeq' "l" "hello"
492−-- > ["he","","o"]
497+-- ["he","","o"]
493--
498--
494-- >>> splitOnSeq' "ll" "hello"
499-- >>> splitOnSeq' "ll" "hello"
495−-- > ["he","o"]
500+-- ["he","o"]
496--
501--
497-- 'splitOnSeq' is an inverse of 'intercalate'. The following law always holds:
502-- 'splitOnSeq' is an inverse of 'intercalate'. The following law always holds:
498--
503--
src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+9−2
@@ -177,6 +177,13 @@ import Prelude hiding
177 , null , reverse, init, and, or, lookup, foldr1, (!!) , splitAt, break
177 , null , reverse, init, and, or, lookup, foldr1, (!!) , splitAt, break
178 , mconcat)
178 , mconcat)
179
179
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+
180------------------------------------------------------------------------------
187------------------------------------------------------------------------------
181-- Deconstruction
188-- Deconstruction
182------------------------------------------------------------------------------
189------------------------------------------------------------------------------
@@ -212,8 +219,8 @@ uncons m = K.uncons (K.adapt m)
212--
219--
213-- Example, determine if any element is 'odd' in a stream:
220-- Example, determine if any element is 'odd' in a stream:
214--
221--
215−-- >>> S.foldrM (\x xs -> if odd x then return True else xs) (return False) $ S.fromList (2:4:5:undefined)
222+-- >>> Stream.foldrM (\x xs -> if odd x then return True else xs) (return False) $ Stream.fromList (2:4:5:undefined)
216−-- > True
223+-- True
217--
224--
218-- /Since: 0.7.0 (signature changed)/
225-- /Since: 0.7.0 (signature changed)/
219--
226--
src/Streamly/Internal/Data/Stream/IsStream/Generate.hs+25−16
@@ -116,13 +116,24 @@ import qualified System.IO as IO
116
116
117import Prelude hiding (iterate, replicate, repeat)
117import Prelude hiding (iterate, replicate, repeat)
118
118
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+
119------------------------------------------------------------------------------
127------------------------------------------------------------------------------
120-- From Unfold
128-- From Unfold
121------------------------------------------------------------------------------
129------------------------------------------------------------------------------
122
130
123-- | Convert an 'Unfold' into a stream by supplying it an input seed.
131-- | Convert an 'Unfold' into a stream by supplying it an input seed.
124--
132--
125−-- >>> unfold (UF.replicateM 10) (putStrLn "hello")
133+-- >>> Stream.drain $ Stream.unfold (Unfold.replicateM 3) (putStrLn "hello")
134+-- hello
135+-- hello
136+-- hello
126--
137--
127-- /Since: 0.7.0/
138-- /Since: 0.7.0/
128{-# INLINE unfold #-}
139{-# INLINE unfold #-}
@@ -278,12 +289,10 @@ replicateMSerial n = fromStreamS . S.replicateM n
278-- (epoch) denoting the start of the stream and the second component is a time
289-- (epoch) denoting the start of the stream and the second component is a time
279-- relative to the reference.
290-- relative to the reference.
280--
291--
281−-- @
282−-- >>> S.mapM_ (\x -> print x >> threadDelay 1000000) $ S.times
292+-- >>> Stream.mapM_ (\x -> print x >> threadDelay 1000000) $ Stream.take 3 $ Stream.times
283−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 0))
293+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
284−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1002028000))
294+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
285−-- > (AbsTime (TimeSpec {sec = 2496295, nsec = 536223000}),RelTime64 (NanoSecond64 1996656000))
295+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
286−-- @
287--
296--
288-- Note: This API is not safe on 32-bit machines.
297-- Note: This API is not safe on 32-bit machines.
289--
298--
@@ -296,9 +305,10 @@ times = timesWith 0.01
296-- | @absTimes@ returns a stream of absolute timestamps using a clock of 10 ms
305-- | @absTimes@ returns a stream of absolute timestamps using a clock of 10 ms
297-- granularity.
306-- granularity.
298--
307--
299−-- @
300−-- >>> S.mapM_ print $ S.delayPre 1 $ S.absTimes
308+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.absTimes
301−-- @
309+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
310+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
311+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
302--
312--
303-- Note: This API is not safe on 32-bit machines.
313-- Note: This API is not safe on 32-bit machines.
304--
314--
@@ -317,9 +327,10 @@ currentTime = absTimesWith
317-- | @relTimes@ returns a stream of relative time values starting from 0,
327-- | @relTimes@ returns a stream of relative time values starting from 0,
318-- using a clock of granularity 10 ms.
328-- using a clock of granularity 10 ms.
319--
329--
320−-- @
321−-- >>> S.mapM_ print $ S.delayPre 1 $ S.relTimes
330+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimes
322−-- @
331+-- RelTime64 (NanoSecond64 ...)
332+-- RelTime64 (NanoSecond64 ...)
333+-- RelTime64 (NanoSecond64 ...)
323--
334--
324-- Note: This API is not safe on 32-bit machines.
335-- Note: This API is not safe on 32-bit machines.
325--
336--
@@ -386,10 +397,8 @@ timeout = undefined
386-- Generate an infinite stream, whose values are the output of a function @f@
397-- Generate an infinite stream, whose values are the output of a function @f@
387-- applied on the corresponding index. Index starts at 0.
398-- applied on the corresponding index. Index starts at 0.
388--
399--
389−-- @
390−-- > Stream.toList $ Stream.take 5 $ Stream.fromIndices id
400+-- >>> Stream.toList $ Stream.take 5 $ Stream.fromIndices id
391-- [0,1,2,3,4]
401-- [0,1,2,3,4]
392−-- @
393--
402--
394-- @since 0.6.0
403-- @since 0.6.0
395{-# INLINE fromIndices #-}
404{-# 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
303
303
304import Prelude hiding (zipWith, concatMap, concat)
304import Prelude hiding (zipWith, concatMap, concat)
305
305
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+
306-------------------------------------------------------------------------------
317-------------------------------------------------------------------------------
307-- Appending
318-- Appending
308-------------------------------------------------------------------------------
319-------------------------------------------------------------------------------
@@ -339,9 +350,10 @@ append m1 m2 = fromStreamD $ D.append (toStreamD m1) (toStreamD m2)
339-- early the other stream continues alone until it too finishes.
350-- early the other stream continues alone until it too finishes.
340--
351--
341-- >>> :set -XOverloadedStrings
352-- >>> :set -XOverloadedStrings
353+-- >>> import Data.Functor.Identity (Identity)
342−-- >>> interleave "ab" ",,,," :: SerialT Identity Char
354+-- >>> Stream.interleave "ab" ",,,," :: Stream.SerialT Identity Char
343-- fromList "a,b,,,"
355-- fromList "a,b,,,"
344−-- >>> interleave "abcd" ",," :: SerialT Identity Char
356+-- >>> Stream.interleave "abcd" ",," :: Stream.SerialT Identity Char
345-- fromList "a,b,cd"
357-- fromList "a,b,cd"
346--
358--
347-- 'interleave' is dual to 'interleaveMin', it can be called @interleaveMax@.
359-- 'interleave' is dual to 'interleaveMin', it can be called @interleaveMax@.
@@ -361,9 +373,10 @@ interleave m1 m2 = fromStreamD $ D.interleave (toStreamD m1) (toStreamD m2)
361-- still continues to yield elements until it finishes.
373-- still continues to yield elements until it finishes.
362--
374--
363-- >>> :set -XOverloadedStrings
375-- >>> :set -XOverloadedStrings
376+-- >>> import Data.Functor.Identity (Identity)
364−-- >>> interleaveSuffix "abc" ",,,," :: SerialT Identity Char
377+-- >>> Stream.interleaveSuffix "abc" ",,,," :: Stream.SerialT Identity Char
365-- fromList "a,b,c,"
378-- fromList "a,b,c,"
366−-- >>> interleaveSuffix "abc" "," :: SerialT Identity Char
379+-- >>> Stream.interleaveSuffix "abc" "," :: Stream.SerialT Identity Char
367-- fromList "a,bc"
380-- fromList "a,bc"
368--
381--
369-- 'interleaveSuffix' is a dual of 'interleaveInfix'.
382-- 'interleaveSuffix' is a dual of 'interleaveInfix'.
@@ -384,9 +397,10 @@ interleaveSuffix m1 m2 =
384-- has finished.
397-- has finished.
385--
398--
386-- >>> :set -XOverloadedStrings
399-- >>> :set -XOverloadedStrings
400+-- >>> import Data.Functor.Identity (Identity)
387−-- >>> interleaveInfix "abc" ",,,," :: SerialT Identity Char
401+-- >>> Stream.interleaveInfix "abc" ",,,," :: Stream.SerialT Identity Char
388-- fromList "a,b,c"
402-- fromList "a,b,c"
389−-- >>> interleaveInfix "abc" "," :: SerialT Identity Char
403+-- >>> Stream.interleaveInfix "abc" "," :: Stream.SerialT Identity Char
390-- fromList "a,bc"
404-- fromList "a,bc"
391--
405--
392-- 'interleaveInfix' is a dual of 'interleaveSuffix'.
406-- 'interleaveInfix' is a dual of 'interleaveSuffix'.
@@ -406,9 +420,10 @@ interleaveInfix m1 m2 =
406-- stream.
420-- stream.
407--
421--
408-- >>> :set -XOverloadedStrings
422-- >>> :set -XOverloadedStrings
423+-- >>> import Data.Functor.Identity (Identity)
409−-- >>> interleaveMin "ab" ",,,," :: SerialT Identity Char
424+-- >>> Stream.interleaveMin "ab" ",,,," :: Stream.SerialT Identity Char
410-- fromList "a,b,"
425-- fromList "a,b,"
411−-- >>> interleaveMin "abcd" ",," :: SerialT Identity Char
426+-- >>> Stream.interleaveMin "abcd" ",," :: Stream.SerialT Identity Char
412-- fromList "a,b,c"
427-- fromList "a,b,c"
413--
428--
414-- 'interleaveMin' is dual to 'interleave'.
429-- 'interleaveMin' is dual to 'interleave'.
@@ -453,8 +468,9 @@ roundrobin m1 m2 = fromStreamD $ D.roundRobin (toStreamD m1) (toStreamD m2)
453-- also remain sorted in ascending order.
468-- also remain sorted in ascending order.
454--
469--
455-- @
470-- @
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])
457-- [1,2,3,4,5,6,8]
472-- [1,2,3,4,5,6,8]
473+--
458-- @
474-- @
459--
475--
460-- @since 0.6.0
476-- @since 0.6.0
@@ -763,10 +779,10 @@ gintercalate unf1 str1 unf2 str2 =
763--
779--
764-- | 'intersperse' followed by unfold and concat.
780-- | 'intersperse' followed by unfold and concat.
765--
781--
766−-- > unwords = intercalate " " UF.fromList
782+-- > unwords = intercalate " " Unfold.fromList
767--
783--
768−-- >>> intercalate " " UF.fromList ["abc", "def", "ghi"]
784+-- >>> Stream.toList $ Stream.intercalate " " Unfold.fromList $ Stream.fromList ["abc", "def", "ghi"]
769−-- > "abc def ghi"
785+-- "abc def ghi"
770--
786--
771-- /Internal/
787-- /Internal/
772{-# INLINE intercalate #-}
788{-# INLINE intercalate #-}
@@ -792,10 +808,10 @@ gintercalateSuffix unf1 str1 unf2 str2 =
792--
808--
793-- | 'intersperseSuffix' followed by unfold and concat.
809-- | 'intersperseSuffix' followed by unfold and concat.
794--
810--
795−-- > unlines = intercalateSuffix "\n" UF.fromList
811+-- > unlines = intercalateSuffix "\n" Unfold.fromList
796--
812--
797−-- >>> intercalate "\n" UF.fromList ["abc", "def", "ghi"]
813+-- >>> Stream.toList $ Stream.intercalateSuffix "\n" Unfold.fromList $ Stream.fromList ["abc", "def", "ghi"]
798−-- > "abc\ndef\nghi\n"
814+-- "abc\ndef\nghi\n"
799--
815--
800-- /Internal/
816-- /Internal/
801{-# INLINE intercalateSuffix #-}
817{-# INLINE intercalateSuffix #-}
@@ -932,11 +948,11 @@ iterateMapLeftsWith combine f = iterateMapWith combine (either f (const K.nil))
932--
948--
933-- >>> f = Fold.takeLE 2 Fold.sum
949-- >>> f = Fold.takeLE 2 Fold.sum
934-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList []
950-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList []
935−-- > [0]
951+-- [0]
936-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList [1..9]
952-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList [1..9]
937−-- > [3,7,11,15,9]
953+-- [3,7,11,15,9]
938-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList [1..10]
954-- >>> Stream.toList $ Stream.foldManyPost f $ Stream.fromList [1..10]
939−-- > [3,7,11,15,19,0]
955+-- [3,7,11,15,19,0]
940--
956--
941-- /Internal/
957-- /Internal/
942--
958--
@@ -955,12 +971,12 @@ foldManyPost f m = D.fromStreamD $ D.foldManyPost f (D.toStreamD m)
955--
971--
956-- >>> f = Fold.takeLE 2 Fold.sum
972-- >>> f = Fold.takeLE 2 Fold.sum
957-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList [1..10]
973-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList [1..10]
958−-- > [3,7,11,15,19]
974+-- [3,7,11,15,19]
959--
975--
960-- On an empty stream the output is empty:
976-- On an empty stream the output is empty:
961--
977--
962-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList []
978-- >>> Stream.toList $ Stream.foldMany f $ Stream.fromList []
963−-- > []
979+-- []
964--
980--
965-- Note @foldMany (takeLE 0)@ would result in an infinite loop in a non-empty
981-- Note @foldMany (takeLE 0)@ would result in an infinite loop in a non-empty
966-- stream.
982-- stream.
@@ -992,10 +1008,14 @@ foldSequence _f _m = undefined
992-- generate the first fold, the fold is applied on the stream and the result of
1008-- generate the first fold, the fold is applied on the stream and the result of
993-- the fold is used to generate the next fold and so on.
1009-- the fold is used to generate the next fold and so on.
994--
1010--
1011+-- @
1012+-- > import Data.Monoid (Sum(..))
995−-- >>> f x = Fold.takeLE 2 (Fold.mconcatTo x)
1013+-- > f x = Fold.takeLE 2 (Fold.sconcat x)
996−-- >>> s = Stream.map Sum $ Stream.fromList [1..10]
1014+-- > s = Stream.map Sum $ Stream.fromList [1..10]
997−-- >>> Stream.toList $ Stream.map getSum $ Stream.foldIterate f 0 s
1015+-- > Stream.toList $ Stream.map getSum $ Stream.foldIterate f 0 s
998−-- > [3,10,21,36,55,55]
1016+-- [3,10,21,36,55,55]
1017+--
1018+-- @
999--
1019--
1000-- This is the streaming equivalent of monad like sequenced application of
1020-- This is the streaming equivalent of monad like sequenced application of
1001-- folds where next fold is dependent on the previous fold.
1021-- folds where next fold is dependent on the previous fold.
@@ -1022,11 +1042,14 @@ foldIterate _f _i _m = undefined
1022-- This is the streaming equivalent of the 'Streamly.Internal.Data.Parser.many'
1042-- This is the streaming equivalent of the 'Streamly.Internal.Data.Parser.many'
1023-- parse combinator.
1043-- parse combinator.
1024--
1044--
1025−-- >>> S.toList $ S.parseMany (PR.take 2 $ PR.fromFold FL.sum) $ S.fromList [1..10]
1045+-- >>> Stream.toList $ Stream.parseMany (Parser.takeBetween 0 2 Fold.sum) $ Stream.fromList [1..10]
1026−-- > [3,7,11,15,19]
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"]
1027--
1051--
1028−-- >>> S.toList $ S.parseMany (PR.line FL.toList) $ S.fromList "hello\nworld"
1052+-- @
1029−-- > ["hello\n","world"]
1030--
1053--
1031-- @
1054-- @
1032-- foldMany f = parseMany (fromFold f)
1055-- foldMany f = parseMany (fromFold f)
@@ -1089,8 +1112,9 @@ parseManyTill = undefined
1089-- used to generate the first parser, the parser is applied on the stream and
1112-- used to generate the first parser, the parser is applied on the stream and
1090-- the result is used to generate the next parser and so on.
1113-- the result is used to generate the next parser and so on.
1091--
1114--
1115+-- >>> import Data.Monoid (Sum(..))
1092−-- >>> S.toList $ S.map getSum $ S.parseIterate (\b -> PR.take 2 (FL.mconcatTo b)) 0 $ S.map Sum $ S.fromList [1..10]
1116+-- >>> Stream.toList $ Stream.map getSum $ Stream.parseIterate (\b -> Parser.takeBetween 0 2 (Fold.sconcat b)) 0 $ Stream.map Sum $ Stream.fromList [1..10]
1093−-- > [3,10,21,36,55,55]
1117+-- [3,10,21,36,55,55]
1094--
1118--
1095-- This is the streaming equivalent of monad like sequenced application of
1119-- This is the streaming equivalent of monad like sequenced application of
1096-- parsers where next parser is dependent on the previous parser.
1120-- parsers where next parser is dependent on the previous parser.
@@ -1196,8 +1220,8 @@ groupScan split fold m = undefined
1196-- group is folded using the fold @f@ and the result of the fold is emitted in
1220-- group is folded using the fold @f@ and the result of the fold is emitted in
1197-- the output stream.
1221-- the output stream.
1198--
1222--
1199−-- >>> S.toList $ S.groupsBy (>) FL.toList $ S.fromList [1,3,7,0,2,5]
1223+-- >>> Stream.toList $ Stream.groupsBy (>) Fold.toList $ Stream.fromList [1,3,7,0,2,5]
1200−-- > [[1,3,7],[0,2,5]]
1224+-- [[1,3,7],[0,2,5]]
1201--
1225--
1202-- @since 0.7.0
1226-- @since 0.7.0
1203{-# INLINE groupsBy #-}
1227{-# INLINE groupsBy #-}
@@ -1217,8 +1241,8 @@ groupsBy cmp f m = D.fromStreamD $ D.groupsBy cmp f (D.toStreamD m)
1217-- comparison fails a new group is started. Each group is folded using the fold
1241-- comparison fails a new group is started. Each group is folded using the fold
1218-- @f@.
1242-- @f@.
1219--
1243--
1220−-- >>> S.toList $ S.groupsByRolling (\a b -> a + 1 == b) FL.toList $ S.fromList [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]
1221−-- > [[1,2,3],[7,8,9]]
1245+-- [[1,2,3],[7,8,9]]
1222--
1246--
1223-- @since 0.7.0
1247-- @since 0.7.0
1224{-# INLINE groupsByRolling #-}
1248{-# INLINE groupsByRolling #-}
@@ -1236,8 +1260,8 @@ groupsByRolling cmp f m = D.fromStreamD $ D.groupsRollingBy cmp f (D.toStreamD
1236--
1260--
1237-- Groups contiguous spans of equal elements together in individual groups.
1261-- Groups contiguous spans of equal elements together in individual groups.
1238--
1262--
1239−-- >>> S.toList $ S.groups FL.toList $ S.fromList [1,1,2,2]
1263+-- >>> Stream.toList $ Stream.groups Fold.toList $ Stream.fromList [1,1,2,2]
1240−-- > [[1,1],[2,2]]
1264+-- [[1,1],[2,2]]
1241--
1265--
1242-- @since 0.7.0
1266-- @since 0.7.0
1243{-# INLINE groups #-}
1267{-# INLINE groups #-}
@@ -1262,9 +1286,9 @@ groups = groupsBy (==)
1262-- separator elements determined by the supplied predicate, separator is
1286-- separator elements determined by the supplied predicate, separator is
1263-- considered as infixed between two segments:
1287-- considered as infixed between two segments:
1264--
1288--
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)
1266-- >>> splitOn' (== '.') "a.b"
1290-- >>> splitOn' (== '.') "a.b"
1267−-- > ["a","b"]
1291+-- ["a","b"]
1268--
1292--
1269-- An empty stream is folded to the default value of the fold:
1293-- An empty stream is folded to the default value of the fold:
1270--
1294--
@@ -1278,13 +1302,13 @@ groups = groupsBy (==)
1278-- ["",""]
1302-- ["",""]
1279--
1303--
1280-- >>> splitOn' (== '.') ".a"
1304-- >>> splitOn' (== '.') ".a"
1281−-- > ["","a"]
1305+-- ["","a"]
1282--
1306--
1283-- >>> splitOn' (== '.') "a."
1307-- >>> splitOn' (== '.') "a."
1284−-- > ["a",""]
1308+-- ["a",""]
1285--
1309--
1286-- >>> splitOn' (== '.') "a..b"
1310-- >>> splitOn' (== '.') "a..b"
1287−-- > ["a","","b"]
1311+-- ["a","","b"]
1288--
1312--
1289-- splitOn is an inverse of intercalating single element:
1313-- splitOn is an inverse of intercalating single element:
1290--
1314--
@@ -1318,12 +1342,12 @@ splitOn predicate f =
1318-- | Split on a suffixed separator element, dropping the separator. The
1342-- | Split on a suffixed separator element, dropping the separator. The
1319-- supplied 'Fold' is applied on the split segments.
1343-- supplied 'Fold' is applied on the split segments.
1320--
1344--
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)
1322-- >>> splitOnSuffix' (== '.') "a.b."
1346-- >>> splitOnSuffix' (== '.') "a.b."
1323−-- > ["a","b"]
1347+-- ["a","b"]
1324--
1348--
1325-- >>> splitOnSuffix' (== '.') "a."
1349-- >>> splitOnSuffix' (== '.') "a."
1326−-- > ["a"]
1350+-- ["a"]
1327--
1351--
1328-- An empty stream results in an empty output stream:
1352-- An empty stream results in an empty output stream:
1329--
1353--
@@ -1337,7 +1361,7 @@ splitOn predicate f =
1337-- [""]
1361-- [""]
1338--
1362--
1339-- >>> splitOnSuffix' (== '.') "a..b.."
1363-- >>> splitOnSuffix' (== '.') "a..b.."
1340−-- > ["a","","b",""]
1364+-- ["a","","b",""]
1341--
1365--
1342-- A suffix is optional at the end of the stream:
1366-- A suffix is optional at the end of the stream:
1343--
1367--
@@ -1345,10 +1369,10 @@ splitOn predicate f =
1345-- ["a"]
1369-- ["a"]
1346--
1370--
1347-- >>> splitOnSuffix' (== '.') ".a"
1371-- >>> splitOnSuffix' (== '.') ".a"
1348−-- > ["","a"]
1372+-- ["","a"]
1349--
1373--
1350-- >>> splitOnSuffix' (== '.') "a.b"
1374-- >>> splitOnSuffix' (== '.') "a.b"
1351−-- > ["a","b"]
1375+-- ["a","b"]
1352--
1376--
1353-- > lines = splitOnSuffix (== '\n')
1377-- > lines = splitOnSuffix (== '\n')
1354--
1378--
@@ -1371,33 +1395,42 @@ splitOnSuffix predicate f = foldMany (FL.sliceSepBy predicate f)
1371-- | Split on a prefixed separator element, dropping the separator. The
1395-- | Split on a prefixed separator element, dropping the separator. The
1372-- supplied 'Fold' is applied on the split segments.
1396-- supplied 'Fold' is applied on the split segments.
1373--
1397--
1398+-- @
1374−-- >>> splitOnPrefix' p xs = S.toList $ S.splitOnPrefix p (FL.toList) (S.fromList xs)
1399+-- > splitOnPrefix' p xs = Stream.toList $ Stream.splitOnPrefix p (Fold.toList) (Stream.fromList xs)
1375−-- >>> splitOnPrefix' (== '.') ".a.b"
1400+-- > splitOnPrefix' (== '.') ".a.b"
1376−-- > ["a","b"]
1401+-- ["a","b"]
1402+-- @
1377--
1403--
1378-- An empty stream results in an empty output stream:
1404-- An empty stream results in an empty output stream:
1405+-- @
1379−-- >>> splitOnPrefix' (== '.') ""
1406+-- > splitOnPrefix' (== '.') ""
1380-- []
1407-- []
1408+-- @
1381--
1409--
1382-- An empty segment consisting of only a prefix is folded to the default output
1410-- An empty segment consisting of only a prefix is folded to the default output
1383-- of the fold:
1411-- of the fold:
1384--
1412--
1413+-- @
1385−-- >>> splitOnPrefix' (== '.') "."
1414+-- > splitOnPrefix' (== '.') "."
1386-- [""]
1415-- [""]
1387--
1416--
1388−-- >>> splitOnPrefix' (== '.') ".a.b."
1417+-- > splitOnPrefix' (== '.') ".a.b."
1418+-- ["a","b",""]
1419+--
1420+-- > splitOnPrefix' (== '.') ".a..b"
1389−-- > ["a","b",""]
1421+-- ["a","","b"]
1390--
1422--
1391−-- >>> splitOnPrefix' (== '.') ".a..b"
1423+-- @
1392−-- > ["a","","b"]
1393--
1424--
1394-- A prefix is optional at the beginning of the stream:
1425-- A prefix is optional at the beginning of the stream:
1395--
1426--
1427+-- @
1396−-- >>> splitOnPrefix' (== '.') "a"
1428+-- > splitOnPrefix' (== '.') "a"
1397-- ["a"]
1429-- ["a"]
1398--
1430--
1399−-- >>> splitOnPrefix' (== '.') "a.b"
1431+-- > splitOnPrefix' (== '.') "a.b"
1400−-- > ["a","b"]
1432+-- ["a","b"]
1433+-- @
1401--
1434--
1402-- 'splitOnPrefix' is an inverse of 'intercalatePrefix' with a single element:
1435-- 'splitOnPrefix' is an inverse of 'intercalatePrefix' with a single element:
1403--
1436--
@@ -1420,16 +1453,16 @@ splitOnPrefix _predicate _f = undefined
1420-- @["a","b"]@. In other words, its like parsing words from whitespace
1453-- @["a","b"]@. In other words, its like parsing words from whitespace
1421-- separated text.
1454-- separated text.
1422--
1455--
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)
1424--
1457--
1425-- >>> wordsBy' (== ',') ""
1458-- >>> wordsBy' (== ',') ""
1426−-- > []
1459+-- []
1427--
1460--
1428-- >>> wordsBy' (== ',') ","
1461-- >>> wordsBy' (== ',') ","
1429−-- > []
1462+-- []
1430--
1463--
1431-- >>> wordsBy' (== ',') ",a,,b,"
1464-- >>> wordsBy' (== ',') ",a,,b,"
1432−-- > ["a","b"]
1465+-- ["a","b"]
1433--
1466--
1434-- > words = wordsBy isSpace
1467-- > words = wordsBy isSpace
1435--
1468--
@@ -1447,7 +1480,7 @@ wordsBy predicate f m =
1447-- | Like 'splitOnSuffix' but keeps the suffix attached to the resulting
1480-- | Like 'splitOnSuffix' but keeps the suffix attached to the resulting
1448-- splits.
1481-- splits.
1449--
1482--
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)
1451--
1484--
1452-- >>> splitWithSuffix' (== '.') ""
1485-- >>> splitWithSuffix' (== '.') ""
1453-- []
1486-- []
@@ -1459,19 +1492,19 @@ wordsBy predicate f m =
1459-- ["a"]
1492-- ["a"]
1460--
1493--
1461-- >>> splitWithSuffix' (== '.') ".a"
1494-- >>> splitWithSuffix' (== '.') ".a"
1462−-- > [".","a"]
1495+-- [".","a"]
1463--
1496--
1464-- >>> splitWithSuffix' (== '.') "a."
1497-- >>> splitWithSuffix' (== '.') "a."
1465−-- > ["a."]
1498+-- ["a."]
1466--
1499--
1467-- >>> splitWithSuffix' (== '.') "a.b"
1500-- >>> splitWithSuffix' (== '.') "a.b"
1468−-- > ["a.","b"]
1501+-- ["a.","b"]
1469--
1502--
1470-- >>> splitWithSuffix' (== '.') "a.b."
1503-- >>> splitWithSuffix' (== '.') "a.b."
1471−-- > ["a.","b."]
1504+-- ["a.","b."]
1472--
1505--
1473-- >>> splitWithSuffix' (== '.') "a..b.."
1506-- >>> splitWithSuffix' (== '.') "a..b.."
1474−-- > ["a.",".","b.","."]
1507+-- ["a.",".","b.","."]
1475--
1508--
1476-- @since 0.7.0
1509-- @since 0.7.0
1477
1510
@@ -1529,34 +1562,34 @@ splitOnAny subseq f m = undefined -- D.fromStreamD $ D.splitOnAny f subseq (D.to
1529--
1562--
1530-- | Like 'splitOnSeq' but splits the separator as well, as an infix token.
1563-- | Like 'splitOnSeq' but splits the separator as well, as an infix token.
1531--
1564--
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)
1533--
1566--
1534-- >>> splitOn'_ "" "hello"
1567-- >>> splitOn'_ "" "hello"
1535−-- > ["h","","e","","l","","l","","o"]
1568+-- ["h","","e","","l","","l","","o"]
1536--
1569--
1537-- >>> splitOn'_ "hello" ""
1570-- >>> splitOn'_ "hello" ""
1538−-- > [""]
1571+-- [""]
1539--
1572--
1540-- >>> splitOn'_ "hello" "hello"
1573-- >>> splitOn'_ "hello" "hello"
1541−-- > ["","hello",""]
1574+-- ["","hello",""]
1542--
1575--
1543-- >>> splitOn'_ "x" "hello"
1576-- >>> splitOn'_ "x" "hello"
1544−-- > ["hello"]
1577+-- ["hello"]
1545--
1578--
1546-- >>> splitOn'_ "h" "hello"
1579-- >>> splitOn'_ "h" "hello"
1547−-- > ["","h","ello"]
1580+-- ["","h","ello"]
1548--
1581--
1549-- >>> splitOn'_ "o" "hello"
1582-- >>> splitOn'_ "o" "hello"
1550−-- > ["hell","o",""]
1583+-- ["hell","o",""]
1551--
1584--
1552-- >>> splitOn'_ "e" "hello"
1585-- >>> splitOn'_ "e" "hello"
1553−-- > ["h","e","llo"]
1586+-- ["h","e","llo"]
1554--
1587--
1555-- >>> splitOn'_ "l" "hello"
1588-- >>> splitOn'_ "l" "hello"
1556−-- > ["he","l","","l","o"]
1589+-- ["he","l","","l","o"]
1557--
1590--
1558-- >>> splitOn'_ "ll" "hello"
1591-- >>> splitOn'_ "ll" "hello"
1559−-- > ["he","ll","o"]
1592+-- ["he","ll","o"]
1560--
1593--
1561-- /Internal/
1594-- /Internal/
1562{-# INLINE splitBySeq #-}
1595{-# INLINE splitBySeq #-}
@@ -1569,7 +1602,7 @@ splitBySeq patt f m =
1569-- | Like 'splitSuffixBy' but the separator is a sequence of elements, instead
1602-- | Like 'splitSuffixBy' but the separator is a sequence of elements, instead
1570-- of a predicate for a single element.
1603-- of a predicate for a single element.
1571--
1604--
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)
1573--
1606--
1574-- >>> splitOnSuffixSeq_ "." ""
1607-- >>> splitOnSuffixSeq_ "." ""
1575-- []
1608-- []
@@ -1581,19 +1614,19 @@ splitBySeq patt f m =
1581-- ["a"]
1614-- ["a"]
1582--
1615--
1583-- >>> splitOnSuffixSeq_ "." ".a"
1616-- >>> splitOnSuffixSeq_ "." ".a"
1584−-- > ["","a"]
1617+-- ["","a"]
1585--
1618--
1586-- >>> splitOnSuffixSeq_ "." "a."
1619-- >>> splitOnSuffixSeq_ "." "a."
1587−-- > ["a"]
1620+-- ["a"]
1588--
1621--
1589-- >>> splitOnSuffixSeq_ "." "a.b"
1622-- >>> splitOnSuffixSeq_ "." "a.b"
1590−-- > ["a","b"]
1623+-- ["a","b"]
1591--
1624--
1592-- >>> splitOnSuffixSeq_ "." "a.b."
1625-- >>> splitOnSuffixSeq_ "." "a.b."
1593−-- > ["a","b"]
1626+-- ["a","b"]
1594--
1627--
1595-- >>> splitOnSuffixSeq_ "." "a..b.."
1628-- >>> splitOnSuffixSeq_ "." "a..b.."
1596−-- > ["a","","b",""]
1629+-- ["a","","b",""]
1597--
1630--
1598-- > lines = splitOnSuffixSeq "\n"
1631-- > lines = splitOnSuffixSeq "\n"
1599--
1632--
@@ -1627,10 +1660,10 @@ wordsOn subseq f m = undefined -- D.fromStreamD $ D.wordsOn f subseq (D.toStream
1627
1660
1628-- | Like 'splitOnSuffixSeq' but keeps the suffix intact in the splits.
1661-- | Like 'splitOnSuffixSeq' but keeps the suffix intact in the splits.
1629--
1662--
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)
1631--
1664--
1632-- >>> splitWithSuffixSeq' "." ""
1665-- >>> splitWithSuffixSeq' "." ""
1633−-- [""]
1666+-- []
1634--
1667--
1635-- >>> splitWithSuffixSeq' "." "."
1668-- >>> splitWithSuffixSeq' "." "."
1636-- ["."]
1669-- ["."]
@@ -1639,19 +1672,19 @@ wordsOn subseq f m = undefined -- D.fromStreamD $ D.wordsOn f subseq (D.toStream
1639-- ["a"]
1672-- ["a"]
1640--
1673--
1641-- >>> splitWithSuffixSeq' "." ".a"
1674-- >>> splitWithSuffixSeq' "." ".a"
1642−-- > [".","a"]
1675+-- [".","a"]
1643--
1676--
1644-- >>> splitWithSuffixSeq' "." "a."
1677-- >>> splitWithSuffixSeq' "." "a."
1645−-- > ["a."]
1678+-- ["a."]
1646--
1679--
1647-- >>> splitWithSuffixSeq' "." "a.b"
1680-- >>> splitWithSuffixSeq' "." "a.b"
1648−-- > ["a.","b"]
1681+-- ["a.","b"]
1649--
1682--
1650-- >>> splitWithSuffixSeq' "." "a.b."
1683-- >>> splitWithSuffixSeq' "." "a.b."
1651−-- > ["a.","b."]
1684+-- ["a.","b."]
1652--
1685--
1653-- >>> splitWithSuffixSeq' "." "a..b.."
1686-- >>> splitWithSuffixSeq' "." "a..b.."
1654−-- > ["a.",".","b.","."]
1687+-- ["a.",".","b.","."]
1655--
1688--
1656-- /Internal/
1689-- /Internal/
1657{-# INLINE splitWithSuffixSeq #-}
1690{-# INLINE splitWithSuffixSeq #-}
@@ -1679,8 +1712,8 @@ splitOnSuffixSeqAny subseq f m = undefined
1679-- | Group the input stream into groups of @n@ elements each and then fold each
1712-- | Group the input stream into groups of @n@ elements each and then fold each
1680-- group using the provided fold function.
1713-- group using the provided fold function.
1681--
1714--
1682−-- >> S.toList $ S.chunksOf 2 FL.sum (S.enumerateFromTo 1 10)
1715+-- >>> Stream.toList $ Stream.chunksOf 2 Fold.sum (Stream.enumerateFromTo 1 10)
1683−-- > [3,7,11,15,19]
1716+-- [3,7,11,15,19]
1684--
1717--
1685-- This can be considered as an n-fold version of 'takeLE' where we apply
1718-- This can be considered as an n-fold version of 'takeLE' where we apply
1686-- 'takeLE' repeatedly on the leftover stream until the stream exhausts.
1719-- 'takeLE' repeatedly on the leftover stream until the stream exhausts.
@@ -1718,12 +1751,13 @@ arraysOf n = D.fromStreamD . A.arraysOf n . D.toStreamD
1718
1751
1719-- XXX we can implement this by repeatedly applying the 'lrunFor' fold.
1752-- XXX we can implement this by repeatedly applying the 'lrunFor' fold.
1720-- XXX add this example after fixing the serial stream rate control
1753-- 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]
1723--
1754--
1724-- | Group the input stream into windows of @n@ second each and then fold each
1755-- | Group the input stream into windows of @n@ second each and then fold each
1725-- group using the provided fold function.
1756-- group using the provided fold function.
1726--
1757--
1758+-- >>> Stream.toList $ Stream.take 5 $ Stream.intervalsOf 1 Fold.sum $ Stream.constRate 2 $ Stream.enumerateFrom 1
1759+-- [...,...,...,...,...]
1760+--
1727-- @since 0.7.0
1761-- @since 0.7.0
1728{-# INLINE intervalsOf #-}
1762{-# INLINE intervalsOf #-}
1729intervalsOf
1763intervalsOf
@@ -2188,12 +2222,18 @@ classifyChunksOf wsize = classifyChunksBy wsize False
2188-- @
2222-- @
2189--
2223--
2190-- @
2224-- @
2225+-- > :{
2191−-- >>> S.mapM_ print
2226+-- Stream.mapM_ print
2192−-- $ S.classifySessionsOf 3 (const (return False)) (fmap Right FL.toList)
2227+-- $ Stream.classifySessionsOf 3 (const (return False)) (fmap Right Fold.toList)
2193−-- $ S.map (\(ts,(k,a)) -> (k, a, ts))
2228+-- $ Stream.map (\\(ts,(k,a)) -> (k, a, ts))
2194−-- $ S.timestamped
2229+-- $ Stream.timestamped
2195−-- $ S.delay 1
2230+-- $ Stream.delay 1
2196−-- $ (,) <$> S.fromList [1,2,3] <*> S.fromList [1,2,3]
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+--
2197-- @
2237-- @
2198--
2238--
2199-- /Internal/
2239-- /Internal/
src/Streamly/Internal/Data/Stream/IsStream/Top.hs+12−8
@@ -78,6 +78,12 @@ import qualified Streamly.Internal.Data.Stream.StreamK as StreamK
78
78
79import Prelude hiding (filter, zipWith, concatMap, concat)
79import Prelude hiding (filter, zipWith, concatMap, concat)
80
80
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+
81------------------------------------------------------------------------------
87------------------------------------------------------------------------------
82-- Sampling
88-- Sampling
83------------------------------------------------------------------------------
89------------------------------------------------------------------------------
@@ -88,10 +94,8 @@ import Prelude hiding (filter, zipWith, concatMap, concat)
88-- | @sampleFromthen offset stride@ samples the element at @offset@ index and
94-- | @sampleFromthen offset stride@ samples the element at @offset@ index and
89-- then every element at strides of @stride@.
95-- then every element at strides of @stride@.
90--
96--
91−-- @
92-- >>> Stream.toList $ Stream.sampleFromThen 2 3 $ Stream.enumerateFromTo 0 10
97-- >>> Stream.toList $ Stream.sampleFromThen 2 3 $ Stream.enumerateFromTo 0 10
93−-- [1,4,7,10]
98+-- [2,5,8]
94−-- @
95--
99--
96-- /Internal/
100-- /Internal/
97--
101--
@@ -468,15 +472,15 @@ mergeOuterJoin _eq _s1 _s2 = undefined
468-- elements in the first stream that are present in the second stream.
472-- elements in the first stream that are present in the second stream.
469--
473--
470-- >>> Stream.toList $ Stream.intersectBy (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [2,1,1,3])
474-- >>> Stream.toList $ Stream.intersectBy (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [2,1,1,3])
471−-- > [1,2,2]
475+-- [1,2,2]
472--
476--
473-- >>> Stream.toList $ Stream.intersectBy (==) (Stream.fromList [2,1,1,3]) (Stream.fromList [1,2,2,4])
477-- >>> Stream.toList $ Stream.intersectBy (==) (Stream.fromList [2,1,1,3]) (Stream.fromList [1,2,2,4])
474−-- > [2,1,1]
478+-- [2,1,1]
475--
479--
476-- 'intersectBy' is similar to but not the same as 'innerJoin':
480-- 'intersectBy' is similar to but not the same as 'innerJoin':
477--
481--
478-- >>> Stream.toList $ fmap fst $ Stream.innerJoin (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [2,1,1,3])
482-- >>> 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]
480--
484--
481-- Space: O(n) where @n@ is the number of elements in the second stream.
485-- Space: O(n) where @n@ is the number of elements in the second stream.
482--
486--
@@ -513,7 +517,7 @@ mergeIntersectBy _eq _s1 _s2 = undefined
513-- second stream as many occurrences of it are deleted from the first stream.
517-- second stream as many occurrences of it are deleted from the first stream.
514--
518--
515-- >>> Stream.toList $ Stream.differenceBy (==) (Stream.fromList [1,2,2]) (Stream.fromList [1,2,3])
519-- >>> Stream.toList $ Stream.differenceBy (==) (Stream.fromList [1,2,2]) (Stream.fromList [1,2,3])
516−-- > [2]
520+-- [2]
517--
521--
518-- The following laws hold:
522-- The following laws hold:
519--
523--
@@ -559,7 +563,7 @@ mergeDifferenceBy _eq _s1 _s2 = undefined
559-- in the first stream.
563-- in the first stream.
560--
564--
561-- >>> Stream.toList $ Stream.unionBy (==) (Stream.fromList [1,2,2,4]) (Stream.fromList [1,1,2,3])
565-- >>> 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]
563--
567--
564-- Equivalent to the following except that @s1@ is evaluated only once:
568-- Equivalent to the following except that @s1@ is evaluated only once:
565--
569--
src/Streamly/Internal/Data/Stream/IsStream/Transform.hs+56−68
@@ -260,6 +260,15 @@ import Prelude hiding
260 ( filter, drop, dropWhile, take, takeWhile, foldr, map, mapM, sequence
260 ( filter, drop, dropWhile, take, takeWhile, foldr, map, mapM, sequence
261 , reverse, foldr1 , scanl, scanl1)
261 , reverse, foldr1 , scanl, scanl1)
262
262
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+
263------------------------------------------------------------------------------
272------------------------------------------------------------------------------
264-- Piping
273-- Piping
265------------------------------------------------------------------------------
274------------------------------------------------------------------------------
@@ -285,18 +294,18 @@ transform pipe xs = fromStreamD $ D.transform pipe (toStreamD xs)
285-- stateful transformations. However, note that the custom map and filter
294-- stateful transformations. However, note that the custom map and filter
286-- routines can be much more efficient than this due to better stream fusion.
295-- routines can be much more efficient than this due to better stream fusion.
287--
296--
288−-- >>> S.toList $ S.foldrS S.cons S.nil $ S.fromList [1..5]
297+-- >>> Stream.toList $ Stream.foldrS Stream.cons Stream.nil $ Stream.fromList [1..5]
289−-- > [1,2,3,4,5]
298+-- [1,2,3,4,5]
290--
299--
291-- Find if any element in the stream is 'True':
300-- Find if any element in the stream is 'True':
292--
301--
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)
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)
294−-- > [True]
303+-- [True]
295--
304--
296-- Map (+2) on odd elements and filter out the even elements:
305-- Map (+2) on odd elements and filter out the even elements:
297--
306--
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)
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)
299−-- > [3,5,7]
308+-- [3,5,7]
300--
309--
301-- 'foldrM' can also be represented in terms of 'foldrS', however, the former
310-- 'foldrM' can also be represented in terms of 'foldrS', however, the former
302-- is much more efficient:
311-- is much more efficient:
@@ -400,11 +409,9 @@ sequence m = fromStreamS $ S.sequence (toStreamS m)
400--
409--
401-- @
410-- @
402--
411--
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)
405-- 1
413-- 1
406-- 2
414-- 2
407−-- @
408--
415--
409-- Compare with 'trace'.
416-- Compare with 'trace'.
410--
417--
@@ -420,10 +427,9 @@ tap f xs = D.fromStreamD $ D.tap f (D.toStreamD xs)
420-- means start at the first element in the stream. If the offset is outside
427-- means start at the first element in the stream. If the offset is outside
421-- this range then @offset `mod` n@ is used as offset.
428-- this range then @offset `mod` n@ is used as offset.
422--
429--
423−-- @
424−-- >>> S.drain $ S.tapOffsetEvery 0 2 (FL.rmapM print FL.toList) $ S.enumerateFromTo 0 10
430+-- >>> Stream.drain $ Stream.tapOffsetEvery 0 2 (Fold.rmapM print Fold.toList) $ Stream.enumerateFromTo 0 10
425−-- > [0,2,4,6,8,10]
431+-- [0,2,4,6,8,10]
426−-- @
432+
427--
433--
428-- /Internal/
434-- /Internal/
429--
435--
@@ -798,8 +804,10 @@ uniq = fromStreamD . D.uniq . toStreamD
798-- prune p = dropWhileAround p $ uniqBy (x y -> p x && p y)
804-- prune p = dropWhileAround p $ uniqBy (x y -> p x && p y)
799-- @
805-- @
800--
806--
807+-- @
801−-- >>> Stream.pruneBy isSpace (Stream.fromList " hello world! ")
808+-- > Stream.pruneBy isSpace (Stream.fromList " hello world! ")
802-- "hello world!"
809-- "hello world!"
810+-- @
803--
811--
804-- Space: @O(1)@
812-- Space: @O(1)@
805--
813--
@@ -1084,10 +1092,8 @@ insertBy cmp x m = fromStreamS $ S.insertBy cmp x (toStreamS m)
1084
1092
1085-- | Insert a pure value between successive elements of a stream.
1093-- | Insert a pure value between successive elements of a stream.
1086--
1094--
1087−-- @
1088−-- > S.toList $ S.intersperse ',' $ S.fromList "hello"
1095+-- >>> Stream.toList $ Stream.intersperse ',' $ Stream.fromList "hello"
1089-- "h,e,l,l,o"
1096-- "h,e,l,l,o"
1090−-- @
1091--
1097--
1092-- @since 0.7.0
1098-- @since 0.7.0
1093{-# INLINE intersperse #-}
1099{-# INLINE intersperse #-}
@@ -1097,10 +1103,8 @@ intersperse a = fromStreamS . S.intersperse a . toStreamS
1097-- | Insert a side effect before consuming an element of a stream except the
1103-- | Insert a side effect before consuming an element of a stream except the
1098-- first one.
1104-- first one.
1099--
1105--
1100−-- @
1101−-- >>> S.drain $ S.trace putChar $ S.intersperseM_ (putChar '.') $ S.fromList "hello"
1106+-- >>> Stream.drain $ Stream.trace putChar $ Stream.intersperseM_ (putChar '.') $ Stream.fromList "hello"
1102−-- > h.e.l.l.o
1107+-- h.e.l.l.o
1103−-- @
1104--
1108--
1105-- /Internal/
1109-- /Internal/
1106{-# INLINE intersperseM_ #-}
1110{-# INLINE intersperseM_ #-}
@@ -1123,10 +1127,8 @@ intersperseBySpan _n _f _xs = undefined
1123
1127
1124-- | Insert an effect and its output after consuming an element of a stream.
1128-- | Insert an effect and its output after consuming an element of a stream.
1125--
1129--
1126−-- @
1127−-- >>> S.toList $ S.trace putChar $ S.intersperseSuffix (putChar '.' >> return ',') $ S.fromList "hello"
1130+-- >>> Stream.toList $ Stream.trace putChar $ intersperseSuffix (putChar '.' >> return ',') $ Stream.fromList "hello"
1128−-- > h.,e.,l.,l.,o.,"h,e,l,l,o,"
1131+-- h.,e.,l.,l.,o.,"h,e,l,l,o,"
1129−-- @
1130--
1132--
1131-- /Internal/
1133-- /Internal/
1132{-# INLINE intersperseSuffix #-}
1134{-# INLINE intersperseSuffix #-}
@@ -1150,10 +1152,8 @@ intersperseSuffix_ m = fromStreamD . D.intersperseSuffix_ m . toStreamD
1150-- | Like 'intersperseSuffix' but intersperses an effectful action into the
1152-- | Like 'intersperseSuffix' but intersperses an effectful action into the
1151-- input stream after every @n@ elements and after the last element.
1153-- input stream after every @n@ elements and after the last element.
1152--
1154--
1153−-- @
1154−-- > S.toList $ S.intersperseSuffixBySpan 2 (return ',') $ S.fromList "hello"
1155+-- >>> Stream.toList $ Stream.intersperseSuffixBySpan 2 (return ',') $ Stream.fromList "hello"
1155-- "he,ll,o,"
1156-- "he,ll,o,"
1156−-- @
1157--
1157--
1158-- /Internal/
1158-- /Internal/
1159--
1159--
@@ -1165,10 +1165,8 @@ intersperseSuffixBySpan n eff =
1165
1165
1166-- | Insert a side effect before consuming an element of a stream.
1166-- | Insert a side effect before consuming an element of a stream.
1167--
1167--
1168−-- @
1169−-- >>> S.toList $ S.trace putChar $ S.interspersePrefix_ (putChar '.' >> return ',') $ S.fromList "hello"
1168+-- >>> Stream.toList $ Stream.trace putChar $ Stream.interspersePrefix_ (putChar '.' >> return ',') $ Stream.fromList "hello"
1170−-- > .h.e.l.l.o"hello"
1169+-- .h.e.l.l.o"hello"
1171−-- @
1172--
1170--
1173-- Same as 'trace_' but may be concurrent.
1171-- Same as 'trace_' but may be concurrent.
1174--
1172--
@@ -1189,12 +1187,10 @@ interspersePrefix_ m = mapM (\x -> void m >> return x)
1189-- | Introduce a delay of specified seconds before consuming an element of the
1187-- | Introduce a delay of specified seconds before consuming an element of the
1190-- stream except the first one.
1188-- stream except the first one.
1191--
1189--
1192−-- @
1193−-- >>> S.mapM_ print $ S.timestamped $ S.delay 1 $ S.enumerateFromTo 1 3
1190+-- >>> Stream.mapM_ print $ Stream.timestamped $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1194−-- > (AbsTime (TimeSpec {sec = 2502706, nsec = 751137000}),1)
1191+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1195−-- > (AbsTime (TimeSpec {sec = 2502707, nsec = 743535000}),2)
1192+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1196−-- > (AbsTime (TimeSpec {sec = 2502708, nsec = 749758000}),3)
1193+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
1197−-- @
1198--
1194--
1199-- /Internal/
1195-- /Internal/
1200--
1196--
@@ -1207,12 +1203,10 @@ delay n = intersperseM_ $ liftIO $ threadDelay $ round $ n * 1000000
1207-- | Introduce a delay of specified seconds after consuming an element of a
1203-- | Introduce a delay of specified seconds after consuming an element of a
1208-- stream.
1204-- stream.
1209--
1205--
1210−-- @
1211−-- >>> S.mapM_ print $ S.timestamped $ S.delayPost 1 $ S.enumerateFromTo 1 3
1206+-- >>> Stream.mapM_ print $ Stream.timestamped $ Stream.delayPost 1 $ Stream.enumerateFromTo 1 3
1212−-- > (AbsTime (TimeSpec {sec = 2502826, nsec = 119030000}),1)
1207+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1213−-- > (AbsTime (TimeSpec {sec = 2502827, nsec = 111393000}),2)
1208+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1214−-- > (AbsTime (TimeSpec {sec = 2502828, nsec = 112221000}),3)
1209+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
1215−-- @
1216--
1210--
1217-- /Internal/
1211-- /Internal/
1218--
1212--
@@ -1225,12 +1219,10 @@ delayPost n = intersperseSuffix_ $ liftIO $ threadDelay $ round $ n * 1000000
1225-- | Introduce a delay of specified seconds before consuming an element of a
1219-- | Introduce a delay of specified seconds before consuming an element of a
1226-- stream.
1220-- stream.
1227--
1221--
1228−-- @
1229−-- >>> S.mapM_ print $ S.timestamped $ S.delayPre 1 $ S.enumerateFromTo 1 3
1222+-- >>> Stream.mapM_ print $ Stream.timestamped $ Stream.delayPre 1 $ Stream.enumerateFromTo 1 3
1230−-- > (AbsTime (TimeSpec {sec = 2502207, nsec = 533177000}),1)
1223+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1231−-- > (AbsTime (TimeSpec {sec = 2502208, nsec = 530859000}),2)
1224+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1232−-- > (AbsTime (TimeSpec {sec = 2502209, nsec = 531619000}),3)
1225+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
1233−-- @
1234--
1226--
1235-- /Internal/
1227-- /Internal/
1236--
1228--
@@ -1267,10 +1259,8 @@ reassembleBy = undefined
1267--
1259--
1268-- Pair each element in a stream with its index, starting from index 0.
1260-- Pair each element in a stream with its index, starting from index 0.
1269--
1261--
1270−-- @
1271−-- > S.toList $ S.indexed $ S.fromList "hello"
1262+-- >>> Stream.toList $ Stream.indexed $ Stream.fromList "hello"
1272-- [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
1263-- [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
1273−-- @
1274--
1264--
1275-- @since 0.6.0
1265-- @since 0.6.0
1276{-# INLINE indexed #-}
1266{-# INLINE indexed #-}
@@ -1284,10 +1274,8 @@ indexed = fromStreamD . D.indexed . toStreamD
1284-- Pair each element in a stream with its index, starting from the
1274-- Pair each element in a stream with its index, starting from the
1285-- given index @n@ and counting down.
1275-- given index @n@ and counting down.
1286--
1276--
1287−-- @
1288−-- > S.toList $ S.indexedR 10 $ S.fromList "hello"
1277+-- >>> Stream.toList $ Stream.indexedR 10 $ Stream.fromList "hello"
1289-- [(10,'h'),(9,'e'),(8,'l'),(7,'l'),(6,'o')]
1278-- [(10,'h'),(9,'e'),(8,'l'),(7,'l'),(6,'o')]
1290−-- @
1291--
1279--
1292-- @since 0.6.0
1280-- @since 0.6.0
1293{-# INLINE indexedR #-}
1281{-# INLINE indexedR #-}
@@ -1309,9 +1297,10 @@ indexedR n = fromStreamD . D.indexedR n . toStreamD
1309-- specified granularity. The timestamp is generated just before the element
1297-- specified granularity. The timestamp is generated just before the element
1310-- is consumed.
1298-- is consumed.
1311--
1299--
1312−-- @
1313−-- >>> S.mapM_ print $ S.timestampWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
1300+-- >>> Stream.mapM_ print $ Stream.timestampWith 0.01 $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1314−-- @
1301+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),1)
1302+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),2)
1303+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),3)
1315--
1304--
1316-- /Internal/
1305-- /Internal/
1317--
1306--
@@ -1333,9 +1322,10 @@ timestamped = timestampWith 0.01
1333-- clock with the specified granularity. The time is measured just before the
1322-- clock with the specified granularity. The time is measured just before the
1334-- element is consumed.
1323-- element is consumed.
1335--
1324--
1336−-- @
1337−-- >>> S.mapM_ print $ S.timeIndexWith 0.01 $ S.delay 1 $ S.enumerateFromTo 1 3
1325+-- >>> Stream.mapM_ print $ Stream.timeIndexWith 0.01 $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1338−-- @
1326+-- (RelTime64 (NanoSecond64 ...),1)
1327+-- (RelTime64 (NanoSecond64 ...),2)
1328+-- (RelTime64 (NanoSecond64 ...),3)
1339--
1329--
1340-- /Internal/
1330-- /Internal/
1341--
1331--
@@ -1348,12 +1338,10 @@ timeIndexWith g stream = Z.zipWith (flip (,)) stream (relTimesWith g)
1348-- 10 ms granularity clock. The time is measured just before the element is
1338-- 10 ms granularity clock. The time is measured just before the element is
1349-- consumed.
1339-- consumed.
1350--
1340--
1351−-- @
1352−-- >>> S.mapM_ print $ S.timeIndexed $ S.delay 1 $ S.enumerateFromTo 1 3
1341+-- >>> Stream.mapM_ print $ Stream.timeIndexed $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
1353−-- (RelTime64 (NanoSecond64 0),1)
1342+-- (RelTime64 (NanoSecond64 ...),1)
1354−-- (RelTime64 (NanoSecond64 996239000),2)
1343+-- (RelTime64 (NanoSecond64 ...),2)
1355−-- (RelTime64 (NanoSecond64 1996712000),3)
1344+-- (RelTime64 (NanoSecond64 ...),3)
1356−-- @
1357--
1345--
1358-- /Internal/
1346-- /Internal/
1359--
1347--
src/Streamly/Internal/Data/Stream/Parallel.hs+28−13
@@ -72,6 +72,13 @@ import qualified Streamly.Internal.Data.Stream.SVar as SVar
72
72
73#include "Instances.hs"
73#include "Instances.hs"
74
74
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+
75-------------------------------------------------------------------------------
82-------------------------------------------------------------------------------
76-- Parallel
83-- Parallel
77-------------------------------------------------------------------------------
84-------------------------------------------------------------------------------
@@ -228,27 +235,28 @@ infixr 6 `parallel`
228-- singleton streams. The following trivial example is semantically equivalent
235-- singleton streams. The following trivial example is semantically equivalent
229-- to running the action @putStrLn "hello"@ in the current thread:
236-- to running the action @putStrLn "hello"@ in the current thread:
230--
237--
231−-- >>> S.toList $ S.yieldM (putStrLn "hello") `parallel` S.nil
238+-- >>> Stream.toList $ Stream.yieldM (putStrLn "hello") `Stream.parallel` Stream.nil
232−-- > hello
239+-- hello
233−-- > [()]
240+-- [()]
234--
241--
235-- Run two actions concurrently:
242-- Run two actions concurrently:
236--
243--
244+-- >>> import Control.Concurrent (threadDelay)
237−-- >>> S.toList $ S.yieldM (putStrLn "hello") `parallel` S.yieldM (putStrLn "world")
245+-- >>> Stream.toList $ Stream.yieldM (putStrLn "hello") `Stream.parallel` Stream.yieldM (threadDelay 100000 >> putStrLn "world")
238−-- > hello
246+-- hello
239−-- > world
247+-- world
240−-- > [(),()]
248+-- [(),()]
241--
249--
242-- Run effects concurrently, disregarding their outputs:
250-- Run effects concurrently, disregarding their outputs:
243--
251--
244−-- >>> S.toList $ S.nilM (putStrLn "hello") `parallel` S.nilM (putStrLn "world")
252+-- >>> Stream.toList $ nilM (putStrLn "hello") `parallel` Stream.nilM (threadDelay 100000 >> putStrLn "world")
245−-- > hello
253+-- hello
246−-- > world
254+-- world
247−-- > []
255+-- []
248--
256--
249-- Run an effectful action, and a pure effect without any output, concurrently:
257-- Run an effectful action, and a pure effect without any output, concurrently:
250--
258--
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")
252-- world
260-- world
253-- [1]
261-- [1]
254--
262--
@@ -449,7 +457,14 @@ tapAsyncF f (D.Stream step1 state1) = D.Stream step TapInit
449-- | Concurrently distribute a stream to a collection of fold functions,
457-- | Concurrently distribute a stream to a collection of fold functions,
450-- discarding the outputs of the folds.
458-- discarding the outputs of the folds.
451--
459--
460+-- @
452−-- >>> S.drain $ distributeAsync_ [S.mapM_ print, S.mapM_ print] (S.enumerateFromTo 1 2)
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+-- @
453--
468--
454-- @
469-- @
455-- distributeAsync_ = flip (foldr tapAsync)
470-- distributeAsync_ = flip (foldr tapAsync)
src/Streamly/Internal/Data/Stream/StreamK.hs+4
@@ -202,6 +202,9 @@ import Streamly.Internal.Data.Stream.StreamK.Type
202
202
203import qualified Streamly.Internal.Data.Fold.Types as FL
203import qualified Streamly.Internal.Data.Fold.Types as FL
204
204
205+-- $setup
206+-- >>> :m
207+
205-------------------------------------------------------------------------------
208-------------------------------------------------------------------------------
206-- Deconstruction
209-- Deconstruction
207-------------------------------------------------------------------------------
210-------------------------------------------------------------------------------
@@ -524,6 +527,7 @@ tailPartial m = mkStream $ \st yld sng stp ->
524-- lazy value @x@ i.e. the same location in memory. Thus @x@ can be defined
527-- lazy value @x@ i.e. the same location in memory. Thus @x@ can be defined
525-- in terms of itself, creating structures with cyclic references.
528-- in terms of itself, creating structures with cyclic references.
526--
529--
530+-- >>> import Data.Function (fix)
527-- >>> f ~(a, b) = ([1, b], head a)
531-- >>> f ~(a, b) = ([1, b], head a)
528-- >>> fix f
532-- >>> fix f
529-- ([1,1],1)
533-- ([1,1],1)
src/Streamly/Internal/Data/Unfold/Types.hs+6
@@ -35,6 +35,12 @@ import Streamly.Internal.Data.Stream.StreamD.Step (Step(..))
35
35
36import Prelude hiding (const, map, concat, concatMap, zipWith)
36import Prelude hiding (const, map, concat, concatMap, zipWith)
37
37
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+
38------------------------------------------------------------------------------
44------------------------------------------------------------------------------
39-- Monadic Unfolds
45-- Monadic Unfolds
40------------------------------------------------------------------------------
46------------------------------------------------------------------------------
src/Streamly/Internal/Unicode/Array/Char.hs+12−5
@@ -26,12 +26,19 @@ import Streamly.Internal.Data.Stream.IsStream (IsStream)
26import qualified Streamly.Internal.Unicode.Stream as S
26import qualified Streamly.Internal.Unicode.Stream as S
27import qualified Streamly.Data.Array.Foreign as A
27import qualified Streamly.Data.Array.Foreign as A
28
28
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+
29-- | Break a string up into a stream of strings at newline characters.
36-- | Break a string up into a stream of strings at newline characters.
30-- The resulting strings do not contain newlines.
37-- The resulting strings do not contain newlines.
31--
38--
32-- > lines = S.lines A.write
39-- > lines = S.lines A.write
33--
40--
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"
35-- ["lines","this","string","",""]
42-- ["lines","this","string","",""]
36--
43--
37{-# INLINE lines #-}
44{-# INLINE lines #-}
@@ -43,8 +50,8 @@ lines = S.lines A.write
43--
50--
44-- > words = S.words A.write
51-- > words = S.words A.write
45--
52--
46−-- >>> S.toList $ words $ S.fromList "A newline\nis considered white space?"
53+-- >>> Stream.toList $ Unicode.words $ Stream.fromList "A newline\nis considered white space?"
47−-- ["A", "newline", "is", "considered", "white", "space?"]
54+-- ["A","newline","is","considered","white","space?"]
48--
55--
49{-# INLINE words #-}
56{-# INLINE words #-}
50words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
57words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
@@ -55,7 +62,7 @@ words = S.words A.write
55--
62--
56-- 'unlines' is an inverse operation to 'lines'.
63-- 'unlines' is an inverse operation to 'lines'.
57--
64--
58−-- >>> S.toList $ unlines $ S.fromList ["lines", "this", "string"]
65+-- >>> Stream.toList $ Unicode.unlines $ Stream.fromList ["lines", "this", "string"]
59-- "lines\nthis\nstring\n"
66-- "lines\nthis\nstring\n"
60--
67--
61-- > unlines = S.unlines A.read
68-- > unlines = S.unlines A.read
@@ -72,7 +79,7 @@ unlines = S.unlines A.read
72--
79--
73-- 'unwords' is an inverse operation to 'words'.
80-- 'unwords' is an inverse operation to 'words'.
74--
81--
75−-- >>> S.toList $ unwords $ S.fromList ["unwords", "this", "string"]
82+-- >>> Stream.toList $ Unicode.unwords $ Stream.fromList ["unwords", "this", "string"]
76-- "unwords this string"
83-- "unwords this string"
77--
84--
78-- > unwords = S.unwords A.read
85-- > 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)
26import qualified Streamly.Internal.Unicode.Stream as S
26import qualified Streamly.Internal.Unicode.Stream as S
27import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
27import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
28
28
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+
29-- | Break a string up into a stream of strings at newline characters.
35-- | Break a string up into a stream of strings at newline characters.
30-- The resulting strings do not contain newlines.
36-- The resulting strings do not contain newlines.
31--
37--
32-- > lines = S.lines A.write
38-- > lines = S.lines A.write
33--
39--
34−-- >>> S.toList $ lines $ S.fromList "lines\nthis\nstring\n\n\n"
40+-- >>> Stream.toList $ Unicode.lines $ Stream.fromList "lines\nthis\nstring\n\n\n"
35−-- ["lines","this","string","",""]
41+-- [fromListN 5 "lines",fromListN 4 "this",fromListN 6 "string",fromListN 0 "",fromListN 0 ""]
36--
42--
37{-# INLINE lines #-}
43{-# INLINE lines #-}
38lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
44lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
@@ -43,8 +49,8 @@ lines = S.lines A.write
43--
49--
44-- > words = S.words A.write
50-- > words = S.words A.write
45--
51--
46−-- >>> S.toList $ words $ S.fromList "A newline\nis considered white space?"
52+-- >>> Stream.toList $ Unicode.words $ Stream.fromList "A newline\nis considered white space?"
47−-- ["A", "newline", "is", "considered", "white", "space?"]
53+-- [fromListN 1 "A",fromListN 7 "newline",fromListN 2 "is",fromListN 10 "considered",fromListN 5 "white",fromListN 6 "space?"]
48--
54--
49{-# INLINE words #-}
55{-# INLINE words #-}
50words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
56words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
@@ -55,7 +61,7 @@ words = S.words A.write
55--
61--
56-- 'unlines' is an inverse operation to 'lines'.
62-- 'unlines' is an inverse operation to 'lines'.
57--
63--
58−-- >>> S.toList $ unlines $ S.fromList ["lines", "this", "string"]
64+-- >>> Stream.toList $ Unicode.unlines $ Stream.fromList ["lines", "this", "string"]
59-- "lines\nthis\nstring\n"
65-- "lines\nthis\nstring\n"
60--
66--
61-- > unlines = S.unlines A.read
67-- > unlines = S.unlines A.read
@@ -72,7 +78,7 @@ unlines = S.unlines A.read
72--
78--
73-- 'unwords' is an inverse operation to 'words'.
79-- 'unwords' is an inverse operation to 'words'.
74--
80--
75−-- >>> S.toList $ unwords $ S.fromList ["unwords", "this", "string"]
81+-- >>> Stream.toList $ Unicode.unwords $ Stream.fromList ["unwords", "this", "string"]
76-- "unwords this string"
82-- "unwords this string"
77--
83--
78-- > unwords = S.unwords A.read
84-- > 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
94
94
95import Prelude hiding (String, lines, words, unlines, unwords)
95import Prelude hiding (String, lines, words, unlines, unwords)
96
96
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+
97-------------------------------------------------------------------------------
104-------------------------------------------------------------------------------
98-- Encoding/Decoding Unicode (UTF-8) Characters
105-- Encoding/Decoding Unicode (UTF-8) Characters
99-------------------------------------------------------------------------------
106-------------------------------------------------------------------------------
@@ -859,8 +866,8 @@ stripStart = S.dropWhile isSpace
859-- | Fold each line of the stream using the supplied 'Fold'
866-- | Fold each line of the stream using the supplied 'Fold'
860-- and stream the result.
867-- and stream the result.
861--
868--
862−-- >>> S.toList $ lines FL.toList (S.fromList "lines\nthis\nstring\n\n\n")
869+-- >>> Stream.toList $ lines Fold.toList (Stream.fromList "lines\nthis\nstring\n\n\n")
863−-- ["lines", "this", "string", "", ""]
870+-- ["lines","this","string","",""]
864--
871--
865-- > lines = S.splitOnSuffix (== '\n')
872-- > lines = S.splitOnSuffix (== '\n')
866--
873--
@@ -884,8 +891,8 @@ isSpace c
884-- | Fold each word of the stream using the supplied 'Fold'
891-- | Fold each word of the stream using the supplied 'Fold'
885-- and stream the result.
892-- and stream the result.
886--
893--
887−-- >>> S.toList $ words FL.toList (S.fromList "fold these words")
894+-- >>> Stream.toList $ words Fold.toList (Stream.fromList "fold these words")
888−-- ["fold", "these", "words"]
895+-- ["fold","these","words"]
889--
896--
890-- > words = S.wordsBy isSpace
897-- > words = S.wordsBy isSpace
891--
898--
src/Streamly/Prelude.hs+20−16
@@ -655,6 +655,10 @@ import Prelude
655
655
656import Streamly.Internal.Data.Stream.IsStream
656import Streamly.Internal.Data.Stream.IsStream
657
657
658+-- $setup
659+-- >>> :m
660+-- >>> import qualified Streamly.Prelude as Stream
661+-- >>> import qualified Streamly.Data.Fold as Fold
658
662
659-- $streamtypes
663-- $streamtypes
660-- The basic stream type is 'Serial', it represents a sequence of IO actions,
664-- The basic stream type is 'Serial', it represents a sequence of IO actions,
@@ -964,9 +968,9 @@ import Streamly.Internal.Data.Stream.IsStream
964-- The following two ways of folding are equivalent in functionality and
968-- The following two ways of folding are equivalent in functionality and
965-- performance,
969-- performance,
966--
970--
967−-- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
971+-- >>> Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
968-- 5050
972-- 5050
969−-- >>> S.sum (S.enumerateFromTo 1 100)
973+-- >>> Stream.sum (Stream.enumerateFromTo 1 100)
970-- 5050
974-- 5050
971--
975--
972-- However, left folds cannot terminate early even if it does not need to
976-- However, left folds cannot terminate early even if it does not need to
@@ -978,30 +982,30 @@ import Streamly.Internal.Data.Stream.IsStream
978-- fold in parallel the performance is not impacted as we anyway have to
982-- fold in parallel the performance is not impacted as we anyway have to
979-- consume the whole stream due to the full fold.
983-- consume the whole stream due to the full fold.
980--
984--
985+-- >>> Stream.head (1 `Stream.cons` undefined)
986+-- Just 1
981−-- >>> S.head (1 `S.cons` undefined)
987+-- >>> Stream.fold Fold.head (1 `Stream.cons` undefined)
982-- Just 1
988-- Just 1
983−-- >>> S.fold FL.head (1 `S.cons` undefined)
984−-- *** Exception: Prelude.undefined
985--
989--
986-- However, we can wrap the fold in a scan to convert it into a lazy stream of
990-- However, we can wrap the fold in a scan to convert it into a lazy stream of
987-- fold steps. We can then terminate the stream whenever we want. For example,
991-- fold steps. We can then terminate the stream whenever we want. For example,
988--
992--
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)
990-- [Nothing]
994-- [Nothing]
991--
995--
992-- The following example extracts the input stream up to a point where the
996-- The following example extracts the input stream up to a point where the
993-- running average of elements is no more than 10:
997-- running average of elements is no more than 10:
994--
998--
995−-- @
999+-- >>> import Data.Maybe (fromJust)
1000+-- >>> let avg = (/) <$> Fold.sum <*> fmap fromIntegral Fold.length
1001+-- >>> :{
996−-- > S.toList
1002+-- Stream.toList
997−-- $ S.map (fromJust . fst)
1003+-- $ Stream.map (fromJust . fst)
998−-- $ S.takeWhile (\\(_,x) -> x <= 10)
1004+-- $ Stream.takeWhile (\(_,x) -> x <= 10)
999−-- $ S.postscan ((,) \<$> FL.last \<*> avg) (S.enumerateFromTo 1.0 100.0)
1005+-- $ Stream.postscan ((,) <$> Fold.last <*> avg) (Stream.enumerateFromTo 1.0 100.0)
1000−-- @
1006+-- :}
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]
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]
1003−-- @
1008+--
1004−
1005-- $application
1009-- $application
1006--
1010--
1007-- Stream processing functions can be composed in a chain using function
1011-- Stream processing functions can be composed in a chain using function