on master help sign in
Add yield and repeat APIs
266148cHarendra Kumar
Changelog.md+5
@@ -4,6 +4,11 @@
4
4
5* `once` has been deprecated and renamed to `yieldM`
5* `once` has been deprecated and renamed to `yieldM`
6
6
7+### Enhancements
8+
9+* Add `yield` to construct a singleton stream from a pure value
10+* Add `repeat` to generate an infinite stream by repeating a pure value
11+
7## 0.3.0
12## 0.3.0
8
13
9### Breaking changes
14### Breaking changes
src/Streamly/Prelude.hs+5−3
@@ -41,10 +41,12 @@ module Streamly.Prelude
41 -- * Construction
41 -- * Construction
42 -- | Primitives to construct or inspect a stream.
42 -- | Primitives to construct or inspect a stream.
43 nil
43 nil
44− , consM
44+ , K.yield
45− , (|:)
45+ , K.yieldM
46 , cons
46 , cons
47 , (.:)
47 , (.:)
48+ , consM
49+ , (|:)
48
50
49 -- * Generation by Unfolding
51 -- * Generation by Unfolding
50 , unfoldr
52 , unfoldr
@@ -53,8 +55,8 @@ module Streamly.Prelude
53 -- * Special Generation
55 -- * Special Generation
54 -- | Generate a monadic stream from an input structure, a seed or a
56 -- | Generate a monadic stream from an input structure, a seed or a
55 -- generation function.
57 -- generation function.
56− , K.yieldM
57 , replicateM
58 , replicateM
59+ , K.repeat
58 , repeatM
60 , repeatM
59 , iterate
61 , iterate
60 , iterateM
62 , iterateM
src/Streamly/Streams/StreamK.hs+11−14
@@ -199,9 +199,14 @@ mkStream k = fromStream $ Stream $ \svr stp sng yld ->
199nil :: IsStream t => t m a
199nil :: IsStream t => t m a
200nil = fromStream $ Stream $ \_ stp _ _ -> stp
200nil = fromStream $ Stream $ \_ stp _ _ -> stp
201
201
202−-- faster than yieldM because there is no bind.
202+-- Faster than yieldM because there is no bind. Usually we can construct a
203+-- stream from a pure value using "pure" in an applicative, however in case of
204+-- Zip streams pure creates an infinite stream.
203−-- | Create a singleton stream from a pure value. Same as @yieldM (return a)@
205+-- | Create a singleton stream from a pure value. In monadic streams, 'pure' or
204−-- but more efficient.
206+-- 'return' can be used in place of 'yield', however, in Zip applicative
207+-- streams 'pure' is equivalent to 'repeat'.
208+--
209+-- @since 0.4.0
205yield :: IsStream t => a -> t m a
210yield :: IsStream t => a -> t m a
206yield a = fromStream $ Stream $ \_ _ single _ -> single a
211yield a = fromStream $ Stream $ \_ _ single _ -> single a
207
212
@@ -257,17 +262,6 @@ infixr 5 .:
257(.:) :: IsStream t => a -> t m a -> t m a
262(.:) :: IsStream t => a -> t m a -> t m a
258(.:) = cons
263(.:) = cons
259
264
260−-- | Constructs a stream by adding a monadic action at the head of an existing
261−-- stream. For example:
262−--
263−-- @
264−-- > toList $ getLine \`consM` getLine \`consM` nil
265−-- hello
266−-- world
267−-- ["hello","world"]
268−-- @
269−--
270−-- @since 0.2.0
271{-# INLINE consMSerial #-}
265{-# INLINE consMSerial #-}
272consMSerial :: (Monad m) => m a -> Stream m a -> Stream m a
266consMSerial :: (Monad m) => m a -> Stream m a -> Stream m a
273consMSerial m r = Stream $ \_ _ _ yld -> m >>= \a -> yld a r
267consMSerial m r = Stream $ \_ _ _ yld -> m >>= \a -> yld a r
@@ -336,6 +330,9 @@ runStream m = go (toStream m)
336-- Special generation
330-- Special generation
337-------------------------------------------------------------------------------
331-------------------------------------------------------------------------------
338
332
333+-- | Generate an infinite stream by repeating a pure value.
334+--
335+-- @since 0.4.0
339repeat :: IsStream t => a -> t m a
336repeat :: IsStream t => a -> t m a
340repeat a = let x = cons a x in x
337repeat a = let x = cons a x in x
341
338
src/Streamly/Tutorial.hs+18−14
@@ -185,7 +185,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
185-- represents a single IO action whereas the 'Serial' monad represents a series
185-- represents a single IO action whereas the 'Serial' monad represents a series
186-- of IO actions. The only change you need to make to go from 'IO' to 'Serial'
186-- of IO actions. The only change you need to make to go from 'IO' to 'Serial'
187-- is to use 'runStream' to run the monad and to prefix the IO actions with
187-- is to use 'runStream' to run the monad and to prefix the IO actions with
188−-- either 'once' or 'liftIO'. If you use liftIO you can switch from 'Serial'
188+-- either 'yieldM' or 'liftIO'. If you use liftIO you can switch from 'Serial'
189-- to IO monad by simply removing the 'runStream' function; no other changes
189-- to IO monad by simply removing the 'runStream' function; no other changes
190-- are needed unless you have used some stream specific composition or
190-- are needed unless you have used some stream specific composition or
191-- combinators.
191-- combinators.
@@ -347,13 +347,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
347-- ["hello","world"]
347-- ["hello","world"]
348-- @
348-- @
349--
349--
350−-- To create a singleton stream from a pure value use 'pure' and to create a
350+-- To create a singleton stream from a pure value use 'yield' or 'pure' and to
351−-- singleton stream from a monadic action use 'once'.
351+-- create a singleton stream from a monadic action use 'yieldM'. Note that in
352+-- case of Zip applicative streams "pure" repeats the value to generate an
353+-- infinite stream.
352--
354--
353-- @
355-- @
354-- > S.'toList' $ 'pure' 1
356-- > S.'toList' $ 'pure' 1
355-- [1]
357-- [1]
356−-- > S.'toList' $ S.'once' 'getLine'
358+-- > S.'toList' $ 'yield' 1
359+-- [1]
360+-- > S.'toList' $ S.'yieldM' 'getLine'
357-- hello
361-- hello
358-- ["hello"]
362-- ["hello"]
359-- @
363-- @
@@ -506,7 +510,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
506-- seconds. After the delay it prints the number of seconds it slept.
510-- seconds. After the delay it prints the number of seconds it slept.
507--
511--
508-- @
512-- @
509−-- delay n = S.'once' $ do
513+-- delay n = S.'yieldM' $ do
510-- threadDelay (n * 1000000)
514-- threadDelay (n * 1000000)
511-- tid \<- myThreadId
515-- tid \<- myThreadId
512-- putStrLn (show tid ++ ": Delay " ++ show n)
516-- putStrLn (show tid ++ ": Delay " ++ show n)
@@ -737,7 +741,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
737--
741--
738-- @
742-- @
739-- main = 'runStream' . 'asyncly' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
743-- main = 'runStream' . 'asyncly' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
740−-- where traced m = S.'once' (myThreadId >>= print) >> return m
744+-- where traced m = S.'yieldM' (myThreadId >>= print) >> return m
741-- @
745-- @
742-- @
746-- @
743-- ThreadId 40
747-- ThreadId 40
@@ -859,7 +863,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
859-- google = get "https://www.google.com/search?q=haskell"
863-- google = get "https://www.google.com/search?q=haskell"
860-- bing = get "https://www.bing.com/search?q=haskell"
864-- bing = get "https://www.bing.com/search?q=haskell"
861-- duckduckgo = get "https://www.duckduckgo.com/?q=haskell"
865-- duckduckgo = get "https://www.duckduckgo.com/?q=haskell"
862−-- get s = S.'once' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
866+-- get s = S.'yieldM' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
863-- @
867-- @
864--
868--
865-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
869-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
@@ -918,7 +922,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
918-- 'runStream' $ 'foldWith' 'async' (map delay [1..10])
922-- 'runStream' $ 'foldWith' 'async' (map delay [1..10])
919-- 'runStream' $ 'foldMapWith' 'async' delay [1..10]
923-- 'runStream' $ 'foldMapWith' 'async' delay [1..10]
920-- 'runStream' $ 'forEachWith' 'async' [1..10] delay
924-- 'runStream' $ 'forEachWith' 'async' [1..10] delay
921−-- where delay n = S.'once' $ threadDelay (n * 1000000) >> print n
925+-- where delay n = S.'yieldM' $ threadDelay (n * 1000000) >> print n
922-- @
926-- @
923
927
924-- $nesting
928-- $nesting
@@ -988,7 +992,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
988-- import "Streamly"
992-- import "Streamly"
989-- import qualified "Streamly.Prelude" as S
993-- import qualified "Streamly.Prelude" as S
990--
994--
991−-- main = 'runStream' $ forever $ S.once getLine >>= S.once . putStrLn
995+-- main = 'runStream' $ forever $ S.yieldM getLine >>= S.yieldM . putStrLn
992-- @
996-- @
993--
997--
994-- When multiple streams are composed using this style they nest in a DFS
998-- When multiple streams are composed using this style they nest in a DFS
@@ -1003,7 +1007,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1003-- main = 'runStream' $ do
1007-- main = 'runStream' $ do
1004-- x <- S.'fromFoldable' [1,2]
1008-- x <- S.'fromFoldable' [1,2]
1005-- y <- S.'fromFoldable' [3,4]
1009-- y <- S.'fromFoldable' [3,4]
1006−-- S.'once' $ putStrLn $ show (x, y)
1010+-- S.'yieldM' $ putStrLn $ show (x, y)
1007-- @
1011-- @
1008-- @
1012-- @
1009-- (1,3)
1013-- (1,3)
@@ -1100,7 +1104,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1100-- main = 'runStream' . 'asyncly' $ do
1104-- main = 'runStream' . 'asyncly' $ do
1101-- x <- S.'fromFoldable' [1,2]
1105-- x <- S.'fromFoldable' [1,2]
1102-- y <- S.'fromFoldable' [3,4]
1106-- y <- S.'fromFoldable' [3,4]
1103−-- S.'once' $ putStrLn $ show (x, y)
1107+-- S.'yieldM' $ putStrLn $ show (x, y)
1104-- @
1108-- @
1105-- @
1109-- @
1106-- (1,3)
1110-- (1,3)
@@ -1125,7 +1129,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1125-- main = 'runStream' . 'wSerially' $ do
1129-- main = 'runStream' . 'wSerially' $ do
1126-- x <- S.'fromFoldable' [1,2]
1130-- x <- S.'fromFoldable' [1,2]
1127-- y <- S.'fromFoldable' [3,4]
1131-- y <- S.'fromFoldable' [3,4]
1128−-- S.once $ putStrLn $ show (x, y)
1132+-- S.yieldM $ putStrLn $ show (x, y)
1129-- @
1133-- @
1130-- @
1134-- @
1131-- (1,3)
1135-- (1,3)
@@ -1153,7 +1157,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1153-- main = 'runStream' . 'wAsyncly' $ do
1157-- main = 'runStream' . 'wAsyncly' $ do
1154-- x <- S.'fromFoldable' [1,2]
1158-- x <- S.'fromFoldable' [1,2]
1155-- y <- S.'fromFoldable' [3,4]
1159-- y <- S.'fromFoldable' [3,4]
1156−-- S.'once' $ putStrLn $ show (x, y)
1160+-- S.'yieldM' $ putStrLn $ show (x, y)
1157-- @
1161-- @
1158-- @
1162-- @
1159-- (1,3)
1163-- (1,3)
@@ -1202,7 +1206,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1202-- sz <- sizes
1206-- sz <- sizes
1203-- cl <- colors
1207-- cl <- colors
1204-- sh <- shapes
1208-- sh <- shapes
1205−-- S.'once' $ putStrLn $ show (sz, cl, sh)
1209+-- S.'yieldM' $ putStrLn $ show (sz, cl, sh)
1206--
1210--
1207-- where
1211-- where
1208--
1212--