on master help sign in
Use StreamD for iterate and iterateM
511fe85adithyaov
benchmark/BaseStreams.hs+2
@@ -194,6 +194,8 @@ main =
194 , benchD "dropOne" D.iterateDropOne
194 , benchD "dropOne" D.iterateDropOne
195 , benchD "dropWhileFalse(1/10)" D.iterateDropWhileFalse
195 , benchD "dropWhileFalse(1/10)" D.iterateDropWhileFalse
196 , benchD "dropWhileTrue" D.iterateDropWhileTrue
196 , benchD "dropWhileTrue" D.iterateDropWhileTrue
197+ , benchD "iterateM" D.iterateM
198+
197 ]
199 ]
198 ]
200 ]
199 , bgroup "list"
201 , bgroup "list"
benchmark/StreamDOps.hs+4
@@ -251,6 +251,10 @@ iterateTakeAll = iterateSource (S.take maxValue) maxIters
251iterateDropOne = iterateSource (S.drop 1) maxIters
251iterateDropOne = iterateSource (S.drop 1) maxIters
252iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
252iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
253
253
254+{-# INLINE iterateM #-}
255+iterateM :: Monad m => Int -> Stream m Int
256+iterateM i = S.take maxIters (S.iterateM (\x -> return (x + 1)) (return i))
257+
254-------------------------------------------------------------------------------
258-------------------------------------------------------------------------------
255-- Zipping and concat
259-- Zipping and concat
256-------------------------------------------------------------------------------
260-------------------------------------------------------------------------------
src/Streamly/Internal/Data/Stream/StreamD.hs+13−1
@@ -78,6 +78,8 @@ module Streamly.Internal.Data.Stream.StreamD
78 , fromIndicesM
78 , fromIndicesM
79 , generate
79 , generate
80 , generateM
80 , generateM
81+ , iterate
82+ , iterateM
81
83
82 -- ** Enumerations
84 -- ** Enumerations
83 , enumerateFromStepIntegral
85 , enumerateFromStepIntegral
@@ -324,7 +326,7 @@ import Prelude
324 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
326 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
325 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
327 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
326 (!!), scanl, scanl1, concatMap, replicate, enumFromTo, concat,
328 (!!), scanl, scanl1, concatMap, replicate, enumFromTo, concat,
327− reverse)
329+ reverse, iterate)
328
330
329import qualified Control.Monad.Catch as MC
331import qualified Control.Monad.Catch as MC
330import qualified Control.Monad.Reader as Reader
332import qualified Control.Monad.Reader as Reader
@@ -448,12 +450,22 @@ unfold (Unfold ustep inject) seed = Stream step Nothing
448-- Specialized Generation
450-- Specialized Generation
449------------------------------------------------------------------------------
451------------------------------------------------------------------------------
450
452
453+{-# INLINE_NORMAL repeatM #-}
451repeatM :: Monad m => m a -> Stream m a
454repeatM :: Monad m => m a -> Stream m a
452repeatM x = Stream (\_ _ -> x >>= \r -> return $ Yield r ()) ()
455repeatM x = Stream (\_ _ -> x >>= \r -> return $ Yield r ()) ()
453
456
457+{-# INLINE_NORMAL repeat #-}
454repeat :: Monad m => a -> Stream m a
458repeat :: Monad m => a -> Stream m a
455repeat x = Stream (\_ _ -> return $ Yield x ()) ()
459repeat x = Stream (\_ _ -> return $ Yield x ()) ()
456
460
461+{-# INLINE_NORMAL iterateM #-}
462+iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
463+iterateM step = Stream (\_ st -> st >>= \x -> return $ Yield x (step x))
464+
465+{-# INLINE_NORMAL iterate #-}
466+iterate :: Monad m => (a -> a) -> a -> Stream m a
467+iterate step st = iterateM (return . step) (return st)
468+
457{-# INLINE_NORMAL replicateM #-}
469{-# INLINE_NORMAL replicateM #-}
458replicateM :: forall m a. Monad m => Int -> m a -> Stream m a
470replicateM :: forall m a. Monad m => Int -> m a -> Stream m a
459replicateM n p = Stream step n
471replicateM n p = Stream step n
src/Streamly/Internal/Data/Stream/StreamK.hs+17−1
@@ -67,6 +67,8 @@ module Streamly.Internal.Data.Stream.StreamK
67 , replicateM
67 , replicateM
68 , fromIndices
68 , fromIndices
69 , fromIndicesM
69 , fromIndicesM
70+ , iterate
71+ , iterateM
70
72
71 -- ** Conversions
73 -- ** Conversions
72 , yield
74 , yield
@@ -196,7 +198,7 @@ import Prelude
196 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
198 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
197 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
199 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
198 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
200 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
199− foldr1, (!!), replicate, reverse, concatMap)
201+ foldr1, (!!), replicate, reverse, concatMap, iterate)
200import qualified Prelude
202import qualified Prelude
201
203
202import Streamly.Internal.Data.SVar
204import Streamly.Internal.Data.SVar
@@ -311,6 +313,20 @@ fromIndices gen = go 0
311 where
313 where
312 go n = (gen n) `cons` go (n + 1)
314 go n = (gen n) `cons` go (n + 1)
313
315
316+{-# INLINE iterate #-}
317+iterate :: IsStream t => (a -> a) -> a -> t m a
318+iterate step = fromStream . go
319+ where
320+ go s = cons s (go (step s))
321+
322+{-# INLINE iterateM #-}
323+iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> m a -> t m a
324+iterateM step = go
325+ where
326+ go s = mkStream $ \st stp sng yld -> do
327+ next <- s
328+ foldStreamShared st stp sng yld (return next |: go (step next))
329+
314-------------------------------------------------------------------------------
330-------------------------------------------------------------------------------
315-- Conversions
331-- Conversions
316-------------------------------------------------------------------------------
332-------------------------------------------------------------------------------
src/Streamly/Internal/Prelude.hs+10−9
@@ -770,10 +770,9 @@ repeatMSerial = fromStreamS . S.repeatM
770-- @
770-- @
771--
771--
772-- @since 0.1.2
772-- @since 0.1.2
773+{-# INLINE_NORMAL iterate #-}
773−iterate :: IsStream t => (a -> a) -> a -> t m a
774+iterate :: (IsStream t, Monad m) => (a -> a) -> a -> t m a
774−iterate step = K.fromStream . go
775+iterate step = fromStreamS . S.iterate step
775− where
776− go s = K.cons s (go (step s))
777
776
778-- |
777-- |
779-- @
778-- @
@@ -802,12 +801,14 @@ iterate step = K.fromStream . go
802-- /Since: 0.7.0 (signature change)/
801-- /Since: 0.7.0 (signature change)/
803--
802--
804-- /Since: 0.1.2/
803-- /Since: 0.1.2/
804+{-# INLINE_EARLY iterateM #-}
805iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> m a -> t m a
805iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> m a -> t m a
806−iterateM step = go
806+iterateM = K.iterateM
807− where
807+
808− go s = K.mkStream $ \st stp sng yld -> do
808+{-# RULES "iterateM serial" iterateM = iterateMSerial #-}
809− next <- s
809+{-# INLINE iterateMSerial #-}
810− K.foldStreamShared st stp sng yld (return next |: go (step next))
810+iterateMSerial :: MonadAsync m => (a -> m a) -> m a -> SerialT m a
811+iterateMSerial step = fromStreamS . S.iterateM step
811
812
812------------------------------------------------------------------------------
813------------------------------------------------------------------------------
813-- Conversions
814-- Conversions