@@ -34,8 +34,11 @@ module Streamly.Streams
3434
3535 -- * Construction
3636 , nil
37+ , once
3738 , cons
3839 , (.:)
40+ , consM
41+ , (|:)
3942 , streamBuild
4043 , fromCallback
4144 , fromSVar
@@ -64,8 +67,6 @@ module Streamly.Streams
6467 , Parallel
6568 , ZipStream
6669 , ZipParallel
67− , fromIO
68− , fromM
6970
7071 -- * Stream Transformers
7172 , StreamT
@@ -122,7 +123,6 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
122123import Data.Semigroup (Semigroup(..))
123124import Prelude hiding (zipWith)
124125import Streamly.Core ( MonadParallel
125− , singleton
126126 , SVar, SVarStyle(..)
127127 , SVarTag(..), SVarSched(..))
128128import qualified Streamly.Core as S
@@ -145,18 +145,59 @@ type Streaming = IsStream
145145-- Constructing a stream
146146------------------------------------------------------------------------------
147147
148−-- | Represesnts an empty stream just like @[]@ represents an empty list.
148+-- | An empty stream.
149+--
150+-- @
151+-- > toList nil
152+-- []
153+-- @
149154nil :: IsStream t => t m a
150155nil = fromStream S.nil
151156
157+-- | Create a single element (singleton) stream from a monadic action.
158+--
159+-- @
160+-- > toList $ once getLine
161+-- hello
162+-- ["hello"]
163+-- @
164+once :: (IsStream t, Monad m) => m a -> t m a
165+once = fromStream . S.once
166+
167+infixr 5 `consM`
168+
169+-- | Constructs a stream by adding a monadic action at the head of an existing
170+-- stream. For example:
171+--
172+-- @
173+-- > toList $ getLine \`consM` getLine \`consM` nil
174+-- hello
175+-- world
176+-- ["hello","world"]
177+-- @
178+consM :: (IsStream t, Monad m) => m a -> t m a -> t m a
179+consM m r = fromStream $ S.consM m (toStream r)
180+
181+infixr 5 |:
182+
183+-- | Operator equivalent of 'consM'.
184+--
185+-- @
186+-- > toList $ getLine |: getLine |: nil
187+-- hello
188+-- world
189+-- ["hello","world"]
190+-- @
191+(|:) :: (IsStream t, Monad m) => m a -> t m a -> t m a
192+(|:) = consM
193+
152194infixr 5 `cons`
153195
154−-- | Constructs a stream by adding a pure value at the head of an existing
155−-- stream, just like ':' constructs lists. For example:
196+-- | Same as @consM . return@. Constructs a stream by adding a pure value at
197+-- the head of an existing stream. For example:
156198--
157199-- @
158−-- > let stream = 1 \`cons` 2 \`cons` 3 \`cons` nil
159−-- > (toList . streamly) stream
200+-- > toList $ 1 \`cons` 2 \`cons` 3 \`cons` nil
160201-- [1,2,3]
161202-- @
162203cons :: IsStream t => a -> t m a -> t m a
@@ -164,32 +205,13 @@ cons a r = fromStream $ S.cons a (toStream r)
164205
165206infixr 5 .:
166207
167−-- | Operator equivalent of 'cons' so that you can construct a stream of pure
168−-- values more succinctly like this:
208+-- | Operator equivalent of 'cons'.
169209--
170210-- @
171−-- > let stream = 1 .: 2 .: 3 .: nil
172−-- > (toList . streamly) stream
211+-- > toList $ 1 .: 2 .: 3 .: nil
173212-- [1,2,3]
174213-- @
175214--
176−-- '.:' constructs a stream just like ':' constructs a list.
177−--
178−-- Also note that another equivalent way of building streams from pure values
179−-- is:
180−--
181−-- @
182−-- > let stream = pure 1 <> pure 2 <> pure 3
183−-- > (toList . streamly) stream
184−-- [1,2,3]
185−-- @
186−--
187−-- In the first method we construct a stream by adding one element at a time.
188−-- In the second method we first construct singleton streams using 'pure' and
189−-- then compose all those streams together using the 'Semigroup' style
190−-- composition of streams. The former method is a bit more efficient than the
191−-- latter.
192−--
193215(.:) :: IsStream t => a -> t m a -> t m a
194216(.:) = cons
195217
@@ -285,7 +307,7 @@ async m = do
285307
286308#define MONAD_APPLICATIVE_INSTANCE(STREAM,CONSTRAINT) \
287309instance (Monad m CONSTRAINT) => Applicative (STREAM m) where { \
288− pure = STREAM . singleton; \
310+ pure = STREAM . S.singleton; \
289311 (<*>) = ap }
290312
291313#define MONAD_COMMON_INSTANCES(STREAM,CONSTRAINT) \
@@ -413,7 +435,7 @@ MONAD_COMMON_INSTANCES(StreamT,)
413435-- yielding one element from each stream alternately.
414436--
415437-- @
416−-- main = ('toList' . 'interleaving' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
438+-- main = ('toList' . 'costreamly' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
417439-- @
418440-- @
419441-- [1,3,2,4]
@@ -424,7 +446,7 @@ MONAD_COMMON_INSTANCES(StreamT,)
424446--
425447--
426448-- @
427−-- main = 'runStream' . 'interleaving' $ do
449+-- main = 'runStream' . 'costreamly' $ do
428450-- x <- return 1 \<\> return 2
429451-- y <- return 3 \<\> return 4
430452-- liftIO $ print (x, y)
@@ -436,7 +458,7 @@ MONAD_COMMON_INSTANCES(StreamT,)
436458-- (2,4)
437459-- @
438460--
439−-- Note that interleaving composition can only combine a finite number of
461+-- Note that costreamly composition can only combine a finite number of
440462-- streams as it needs to retain state for each unfinished stream.
441463--
442464newtype CostreamT m a = CostreamT {getCostreamT :: S.Stream m a}
@@ -899,15 +921,6 @@ type ZipStream a = ZipStreamM IO a
899921-- | An IO stream whose applicative instance zips streams parallely.
900922type ZipParallel a = ZipParallelM IO a
901923
902−-- | Lift a value from IO monad to any of the stream types. This works for all
903−-- stream types including those that are not monads e.g. 'ZipStream' and
904−-- 'ZipParallel'.
905−fromIO :: (IsStream t, MonadIO m) => IO a -> t m a
906−fromIO = streamly . liftIO
907−
908−fromM :: (IsStream t, Monad m) => m a -> t m a
909−fromM = streamly . lift
910−
911924------------------------------------------------------------------------------
912925-- Fold Utilities
913926------------------------------------------------------------------------------