on master help sign in
Add intersperseSuffixBySpan
f336d57Harendra Kumar
src/Streamly/Internal/Prelude.hs+17
@@ -208,6 +208,7 @@ module Streamly.Internal.Prelude
208 , intersperseM
208 , intersperseM
209 , intersperse
209 , intersperse
210 , intersperseSuffix
210 , intersperseSuffix
211+ , intersperseSuffixBySpan
211 -- , intersperseBySpan
212 -- , intersperseBySpan
212 , interjectSuffix
213 , interjectSuffix
213
214
@@ -1895,6 +1896,22 @@ intersperse a = fromStreamS . S.intersperse a . toStreamS
1895intersperseSuffix :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
1896intersperseSuffix :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
1896intersperseSuffix m = fromStreamD . D.intersperseSuffix m . toStreamD
1897intersperseSuffix m = fromStreamD . D.intersperseSuffix m . toStreamD
1897
1898
1899+-- | Like 'intersperseSuffix' but intersperses a monadic action into the input
1900+-- stream after every @n@ elements and after the last element.
1901+--
1902+-- @
1903+-- > S.toList $ S.intersperseSuffixBySpan 2 (return ',') $ S.fromList "hello"
1904+-- "he,ll,o,"
1905+-- @
1906+--
1907+-- /Internal/
1908+--
1909+{-# INLINE intersperseSuffixBySpan #-}
1910+intersperseSuffixBySpan :: (IsStream t, MonadAsync m)
1911+ => Int -> m a -> t m a -> t m a
1912+intersperseSuffixBySpan n eff =
1913+ fromStreamD . D.intersperseSuffixBySpan n eff . toStreamD
1914+
1898{-
1915{-
1899-- | Intersperse a monadic action into the input stream after every @n@
1916-- | Intersperse a monadic action into the input stream after every @n@
1900-- elements.
1917-- elements.
src/Streamly/Streams/StreamD.hs+34
@@ -244,6 +244,7 @@ module Streamly.Streams.StreamD
244 , intersperseM
244 , intersperseM
245 , intersperse
245 , intersperse
246 , intersperseSuffix
246 , intersperseSuffix
247+ , intersperseSuffixBySpan
247 , insertBy
248 , insertBy
248
249
249 -- * Deleting
250 -- * Deleting
@@ -3266,6 +3267,39 @@ intersperseSuffix action (Stream step state) = Stream step' (SuffixElem state)
3266
3267
3267 step' _ (SuffixYield x next) = return $ Yield x next
3268 step' _ (SuffixYield x next) = return $ Yield x next
3268
3269
3270+data SuffixSpanState s a
3271+ = SuffixSpanElem s Int
3272+ | SuffixSpanSuffix s
3273+ | SuffixSpanYield a (SuffixSpanState s a)
3274+ | SuffixSpanLast
3275+ | SuffixSpanStop
3276+
3277+-- | intersperse after every n items
3278+{-# INLINE_NORMAL intersperseSuffixBySpan #-}
3279+intersperseSuffixBySpan :: forall m a. Monad m
3280+ => Int -> m a -> Stream m a -> Stream m a
3281+intersperseSuffixBySpan n action (Stream step state) =
3282+ Stream step' (SuffixSpanElem state n)
3283+ where
3284+ {-# INLINE_LATE step' #-}
3285+ step' gst (SuffixSpanElem st i) | i > 0 = do
3286+ r <- step gst st
3287+ return $ case r of
3288+ Yield x s -> Skip (SuffixSpanYield x (SuffixSpanElem s (i - 1)))
3289+ Skip s -> Skip (SuffixSpanElem s i)
3290+ Stop -> if i == n then Stop else Skip SuffixSpanLast
3291+ step' _ (SuffixSpanElem st _) = return $ Skip (SuffixSpanSuffix st)
3292+
3293+ step' _ (SuffixSpanSuffix st) = do
3294+ action >>= \r -> return $ Skip (SuffixSpanYield r (SuffixSpanElem st n))
3295+
3296+ step' _ (SuffixSpanLast) = do
3297+ action >>= \r -> return $ Skip (SuffixSpanYield r SuffixSpanStop)
3298+
3299+ step' _ (SuffixSpanYield x next) = return $ Yield x next
3300+
3301+ step' _ (SuffixSpanStop) = return Stop
3302+
3269{-# INLINE intersperse #-}
3303{-# INLINE intersperse #-}
3270intersperse :: Monad m => a -> Stream m a -> Stream m a
3304intersperse :: Monad m => a -> Stream m a -> Stream m a
3271intersperse a = intersperseM (return a)
3305intersperse a = intersperseM (return a)