@@ -61,6 +61,7 @@ module Streamly.Internal.Prelude
6161 , K.fromFoldable
6262 , fromFoldableM
6363 , fromPrimVar
64+ , fromCallback
6465
6566 -- ** Time related
6667 , currentTime
@@ -277,6 +278,7 @@ module Streamly.Internal.Prelude
277278
278279 -- ** Nested Streams
279280 , concatMapM
281+ , concatM
280282 , concatUnfold
281283 , concatUnfoldInterleave
282284 , concatUnfoldRoundrobin
@@ -905,6 +907,19 @@ fromHandle h = go
905907fromPrimVar :: (IsStream t, MonadIO m, Prim a) => Var IO a -> t m a
906908fromPrimVar = fromStreamD . D.fromPrimVar
907909
910+-- | Takes a callback setter function and provides it with a callback. The
911+-- callback when invoked adds a value at the tail of the stream. Returns a
912+-- stream of values generated by the callback.
913+--
914+-- /Internal/
915+--
916+{-# INLINE fromCallback #-}
917+fromCallback :: MonadAsync m => ((a -> m ()) -> m ()) -> SerialT m a
918+fromCallback setCallback = concatM $ do
919+ (callback, stream) <- D.newCallbackStream
920+ setCallback callback
921+ return stream
922+
908923------------------------------------------------------------------------------
909924-- Time related
910925------------------------------------------------------------------------------
@@ -2612,6 +2627,15 @@ roundrobin m1 m2 = fromStreamD $ D.roundRobin (toStreamD m1) (toStreamD m2)
26122627concatMapM :: (IsStream t, Monad m) => (a -> m (t m b)) -> t m a -> t m b
26132628concatMapM f m = fromStreamD $ D.concatMapM (fmap toStreamD . f) (toStreamD m)
26142629
2630+-- | Given a stream value in the underlying monad, lift and join the underlying
2631+-- monad with the stream monad.
2632+--
2633+-- /Internal/
2634+--
2635+{-# INLINE concatM #-}
2636+concatM :: (IsStream t, Monad m) => m (t m a) -> t m a
2637+concatM generator = concatMapM (\() -> generator) (K.yield ())
2638+
26152639-- | Like 'concatMap' but uses an 'Unfold' for stream generation. Unlike
26162640-- 'concatMap' this can fuse the 'Unfold' code with the inner loop and
26172641-- therefore provide many times better performance.