@@ -58,6 +58,8 @@ module Streamly.Streams.StreamD
58 -- | Direct style stream does not support @fromFoldable@.
58 -- | Direct style stream does not support @fromFoldable@.
61 , fromList
63 , fromList
62 , fromListM
64 , fromListM
63 , fromStreamK
65 , fromStreamK
@@ -87,8 +89,11 @@ module Streamly.Streams.StreamD
87 , minimumBy
89 , minimumBy
88 , findIndices
90 , findIndices
93 -- ** Substreams
98 -- ** Substreams
94 , isPrefixOf
99 , isPrefixOf
@@ -162,7 +167,7 @@ import Prelude
162 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
167 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
163 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
168 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
164 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
169 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
165− (!!), scanl, scanl1)
170+ (!!), scanl, scanl1, concatMap)
167import Streamly.SVar (MonadAsync, State(..), defState, rstState)
172import Streamly.SVar (MonadAsync, State(..), defState, rstState)
@@ -285,6 +290,20 @@ yieldM m = Stream step True
285 step _ True = m >>= \x -> return $ Yield x False
290 step _ True = m >>= \x -> return $ Yield x False
286 step _ False = return Stop
291 step _ False = return Stop
293+{-# INLINE generate #-}
294+generate :: Monad m => Int -> (Int -> a) -> Stream m a
295+generate n gen = generateM n (return . gen)
297+{-# INLINE_NORMAL generateM #-}
298+generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
299+generateM n gen = n `seq` Stream step 0
301+ {-# INLINE_LATE step #-}
302+ step _ i | i < n = do
304+ return $ Yield x (i+1)
305+ | otherwise = return Stop
288-- XXX we need the MonadAsync constraint because of a rewrite rule.
307-- XXX we need the MonadAsync constraint because of a rewrite rule.
289-- | Convert a list of monadic actions to a 'Stream'
308-- | Convert a list of monadic actions to a 'Stream'
290{-# INLINE_LATE fromListM #-}
309{-# INLINE_LATE fromListM #-}
@@ -562,17 +581,23 @@ lookup e (Stream step state) = go state
562 Skip s -> go s
581 Skip s -> go s
563 Stop -> return Nothing
582 Stop -> return Nothing
565−{-# INLINE_NORMAL find #-}
584+{-# INLINE_NORMAL findM #-}
566−find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
585+findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
567−find p (Stream step state) = go state
586+findM p (Stream step state) = go SPEC state
569− go st = do
588+ go !_ st = do
570 r <- step defState st
589 r <- step defState st
571 case r of
590 case r of
572− Yield x s -> if p x then return (Just x) else go s
593+ if b then return (Just x) else go SPEC s
573− Skip s -> go s
594+ Skip s -> go SPEC s
574 Stop -> return Nothing
595 Stop -> return Nothing
598+find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
599+find p = findM (return . p)
576{-# INLINE_NORMAL findIndices #-}
601{-# INLINE_NORMAL findIndices #-}
577findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
602findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
578findIndices p (Stream step state) = Stream step' (state, 0)
603findIndices p (Stream step state) = Stream step' (state, 0)
@@ -585,6 +610,32 @@ findIndices p (Stream step state) = Stream step' (state, 0)
585 Skip s -> Skip (s, i+1)
610 Skip s -> Skip (s, i+1)
586 Stop -> Stop
611 Stop -> Stop
613+{-# INLINE concatMap #-}
614+concatMap :: Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
615+concatMap f = concatMapM (return . f)
617+{-# INLINE_NORMAL concatMapM #-}
618+concatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
619+concatMapM f (Stream step state) = Stream step' (Left state)
621+ step' gst (Left st) = do
622+ r <- step (rstState gst) st
626+ return $ Skip (Right (b_stream, s))
627+ Skip s -> return $ Skip (Left s)
630+ step' _ (Right (Stream inner_step inner_st, st)) = do
631+ r <- inner_step defState inner_st
634+ return $ Yield b (Right (Stream inner_step inner_s, st))
636+ return $ Skip (Right (Stream inner_step inner_s, st))
637+ Stop -> return $ Skip (Left st)
588------------------------------------------------------------------------------
639------------------------------------------------------------------------------
589-- Substreams
640-- Substreams
590------------------------------------------------------------------------------
641------------------------------------------------------------------------------