on ffca3ac help sign in
111 lines 3.2 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.Stream.Generate
3-- Copyright : (c) 2017 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
7-- Portability : GHC
8--
9module Streamly.Internal.Data.Stream.Generate
10 (
11 cons
12 , consM
13 , unfold
14 , append
15 )
16where
18#if __GLASGOW_HASKELL__ < 808
19import Data.Semigroup (Semigroup(..))
20#endif
21#if __GLASGOW_HASKELL__ < 808
22import Data.Semigroup (Semigroup(..))
23#endif
24import Streamly.Internal.Data.Stream.Type (Stream)
25import Streamly.Internal.Data.Unfold (Unfold)
27import qualified Streamly.Internal.Data.Stream.Type as Stream
28import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
29import qualified Streamly.Internal.Data.Stream.StreamK.Type as StreamK
31-- $setup
32-- >>> :m
33-- >>> import qualified Streamly.Data.Fold as Fold
34-- >>> import qualified Streamly.Data.Unfold as Unfold
35-- >>> import qualified Streamly.Internal.Data.Stream as Stream
37infixr 5 `cons`
39-- | Construct a stream by adding a pure value at the head of an existing
40-- stream. Same as the following but more efficient:
41--
42-- For example:
43--
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
49--
50-- /Pre-release/
51--
52{-# INLINE cons #-}
53cons :: a -> Stream m a -> Stream m a
54cons x = Stream.fromStreamK . StreamK.cons x . Stream.toStreamK
56infixr 5 `consM`
58-- | Constructs a stream by adding a monadic action at the head of an
59-- existing stream. For example:
60--
61-- >> s = putChar 'h' `Stream.consM` putChar 'i' `Stream.consM` Stream.nil
62-- >> Stream.fold Fold.toList s
63-- >hi
64--
65-- >> consM x xs = Stream.fromEffect x `Stream.append` xs
66--
67-- /Pre-release/
68--
69{-# INLINE consM #-}
70{-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
71consM :: Monad m => m a -> Stream m a -> Stream m a
72consM m = Stream.fromStreamK . StreamK.consM m . Stream.toStreamK
74------------------------------------------------------------------------------
75-- From Unfold
76------------------------------------------------------------------------------
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 #-}
88unfold :: Monad m => Unfold m a b -> a -> Stream m b
89unfold unf = Stream.fromStreamD . StreamD.unfold unf
91------------------------------------------------------------------------------
92-- Combining
93------------------------------------------------------------------------------
95infixr 6 `append`
97-- | Appends two streams sequentially, yielding all elements from the first
98-- stream, and then all elements from the second stream.
99--
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
103-- [1,2,3,4]
104--
105-- This operation can be used to fold an infinite lazy container of streams.
106--
107-- /Pre-release/
108--
109{-# INLINE append #-}
110append :: Stream m a -> Stream m a -> Stream m a
111append = (<>)