@@ -10,6 +10,7 @@ module Streamly.Internal.Data.Stream.Generate
1010 (
1111 cons
1212 , consM
13+ , unfold
1314 , append
1415 )
1516where
@@ -21,27 +22,30 @@ import Data.Semigroup (Semigroup(..))
2122import Data.Semigroup (Semigroup(..))
2223#endif
2324import Streamly.Internal.Data.Stream.Type (Stream)
25+import Streamly.Internal.Data.Unfold (Unfold)
2426
2527import qualified Streamly.Internal.Data.Stream.Type as Stream
28+import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
2629import qualified Streamly.Internal.Data.Stream.StreamK.Type as StreamK
2730
2831-- $setup
2932-- >>> :m
30−-- >>> import Control.Concurrent (threadDelay)
31−-- >>> import Data.IORef
32−-- >>> import Prelude hiding (zipWith, concatMap, concat)
33+-- >>> import qualified Streamly.Data.Fold as Fold
34+-- >>> import qualified Streamly.Data.Unfold as Unfold
3335-- >>> import qualified Streamly.Internal.Data.Stream as Stream
34−--
36+
37+infixr 5 `cons`
3538
3639-- | Construct a stream by adding a pure value at the head of an existing
37−-- stream. This is the same as @(return a) \`consM` r@ but
38−-- more efficient. For concurrent streams this is not concurrent whereas
39−-- 'consM' is concurrent. For example:
40+-- stream. Same as the following but more efficient:
41+--
42+-- For example:
4043--
41−-- @
42−-- > toList $ 1 \`cons` 2 \`cons` 3 \`cons` nil
43−-- [1,2,3]
44−-- @
44+-- >> s = 1 `Stream.cons` 2 `Stream.cons` 3 `Stream.cons` Stream.nil
45+-- >> Stream.fold Fold.toList s
46+-- >[1,2,3]
47+--
48+-- >>> cons x xs = return x `Stream.consM` xs
4549--
4650-- /Pre-release/
4751--
@@ -49,17 +53,16 @@ import qualified Streamly.Internal.Data.Stream.StreamK.Type as StreamK
4953cons :: a -> Stream m a -> Stream m a
5054cons x = Stream.fromStreamK . StreamK.cons x . Stream.toStreamK
5155
56+infixr 5 `consM`
57+
5258-- | Constructs a stream by adding a monadic action at the head of an
5359-- existing stream. For example:
5460--
55−-- @
56−-- > toList $ getLine \`consM` getLine \`consM` nil
57−-- hello
58−-- world
59−-- ["hello","world"]
60−-- @
61+-- >> s = putChar 'h' `Stream.consM` putChar 'i' `Stream.consM` Stream.nil
62+-- >> Stream.fold Fold.toList s
63+-- >hi
6164--
62−-- > consM x xs = fromEffect x `append` xs
65+-- >> consM x xs = Stream.fromEffect x `Stream.append` xs
6366--
6467-- /Pre-release/
6568--
@@ -68,17 +71,35 @@ cons x = Stream.fromStreamK . StreamK.cons x . Stream.toStreamK
6871consM :: Monad m => m a -> Stream m a -> Stream m a
6972consM m = Stream.fromStreamK . StreamK.consM m . Stream.toStreamK
7073
74+------------------------------------------------------------------------------
75+-- From Unfold
76+------------------------------------------------------------------------------
77+
78+-- | Convert an 'Unfold' into a stream by supplying it an input seed.
79+--
80+-- >>> s = Stream.unfold (Unfold.replicateM 3) (putStrLn "hello")
81+-- >>> Stream.fold Fold.drain s
82+-- hello
83+-- hello
84+-- hello
85+--
86+-- /Pre-release/
87+{-# INLINE unfold #-}
88+unfold :: Monad m => Unfold m a b -> a -> Stream m b
89+unfold unf = Stream.fromStreamD . StreamD.unfold unf
90+
7191------------------------------------------------------------------------------
7292-- Combining
7393------------------------------------------------------------------------------
7494
95+infixr 6 `append`
96+
7597-- | Appends two streams sequentially, yielding all elements from the first
7698-- stream, and then all elements from the second stream.
7799--
78−-- >>> import Streamly.Internal.Data.Stream (append)
79−-- >>> stream1 = Stream.fromList [1,2]
80−-- >>> stream2 = Stream.fromList [3,4]
81−-- >>> Stream.toList $ stream1 `append` stream2
100+-- >>> s1 = Stream.unfold Unfold.fromList [1,2]
101+-- >>> s2 = Stream.unfold Unfold.fromList [3,4]
102+-- >>> Stream.fold Fold.toList $ s1 `Stream.append` s2
82103-- [1,2,3,4]
83104--
84105-- This operation can be used to fold an infinite lazy container of streams.