@@ -47,11 +47,11 @@ module Streamly.Prelude
48 -- * Construction
48 -- * Construction
49 -- | Primitives to construct or inspect a stream.
49 -- | Primitives to construct or inspect a stream.
52 , K.yieldM
52 , K.yieldM
@@ -116,6 +116,7 @@ module Streamly.Prelude
116 , reverse
116 , reverse
118 -- * Mapping
118 -- * Mapping
120 , mapMaybe
121 , mapMaybe
121 , mapMaybeM
122 , mapMaybeM
@@ -140,25 +141,24 @@ module Streamly.Prelude
143−import Control.Monad (void)
144−import Control.Monad.IO.Class (MonadIO(..))
144+import Control.Monad.IO.Class (MonadIO(..))
145−import Data.Maybe (isJust, fromJust)
145+import Data.Maybe (isJust, fromJust)
146−import Prelude hiding (filter, drop, dropWhile, take,
147+ hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
147− takeWhile, zipWith, foldr, foldl,
148− mapM, mapM_, sequence, all, any,
148+ foldl, map, mapM, mapM_, sequence, all, any, sum, product, elem,
149− sum, product, elem, notElem,
150− maximum, minimum, head, last,
149+ notElem, maximum, minimum, head, last, tail, length, null,
151− tail, length, null, reverse,
152− iterate)
150+ reverse, iterate)
153import qualified Prelude
151import qualified Prelude
154import qualified System.IO as IO
152import qualified System.IO as IO
154+import Streamly.SVar (MonadAsync)
156−import Streamly.Streams.StreamK (IsStream(..), cons, nil, (.:))
155+import Streamly.Streams.StreamK (IsStream(..))
156+import Streamly.Streams.Serial (SerialT)
157+import Streamly.Streams.Zip (zipWith, zipWithM, zipAsyncWith, zipAsyncWithM)
157import qualified Streamly.Streams.StreamK as K
159import qualified Streamly.Streams.StreamK as K
158import qualified Streamly.Streams.StreamD as D
160import qualified Streamly.Streams.StreamD as D
159−import Streamly.Streams.Zip
160−import Streamly.Streams.Serial
161+import qualified Streamly.Streams.Serial as Serial
161−import Streamly.SVar (MonadAsync)
163------------------------------------------------------------------------------
163------------------------------------------------------------------------------
164-- Construction
164-- Construction
@@ -260,7 +260,7 @@ fromListM = fromStream . D.toStreamK . D.fromListM
260-- @since 0.3.0
260-- @since 0.3.0
261{-# INLINE fromFoldableM #-}
261{-# INLINE fromFoldableM #-}
262fromFoldableM :: (IsStream t, MonadAsync m, Foldable f) => f (m a) -> t m a
262fromFoldableM :: (IsStream t, MonadAsync m, Foldable f) => f (m a) -> t m a
263−fromFoldableM = Prelude.foldr consM nil
263+fromFoldableM = Prelude.foldr consM K.nil
265-- | Same as 'fromFoldable'.
265-- | Same as 'fromFoldable'.
@@ -284,7 +284,7 @@ each = K.fromFoldable
284replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
284replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
285replicateM n m = go n
285replicateM n m = go n
287− go cnt = if cnt <= 0 then nil else m |: go (cnt - 1)
287+ go cnt = if cnt <= 0 then K.nil else m |: go (cnt - 1)
289-- | Generate a stream by repeatedly executing a monadic action forever.
289-- | Generate a stream by repeatedly executing a monadic action forever.
@@ -360,14 +360,11 @@ fromHandle h = fromStream go
362-- @since 0.1.0
362-- @since 0.1.0
363foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
364foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
365+-- XXX somehow this definition does not perform well, need to investigate
364−foldr step acc m = go (toStream m)
366+-- foldr step acc m = D.foldr step acc $ D.fromStreamK (toStream m)
365− where
367+foldr f = foldrM (\a b -> return (f a b))
367− let stop = return acc
368− single a = return (step a acc)
369− yieldk a r = go r >>= \b -> return (step a b)
370− in (K.unStream m1) Nothing stop single yieldk
372-- | Lazy right fold with a monadic step function. For example, to fold a
369-- | Lazy right fold with a monadic step function. For example, to fold a
373-- stream into a list:
370-- stream into a list:
@@ -380,13 +377,7 @@ foldr step acc m = go (toStream m)
380-- @since 0.2.0
377-- @since 0.2.0
381{-# INLINE foldrM #-}
378{-# INLINE foldrM #-}
382foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
379foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
383−foldrM step acc m = go (toStream m)
380+foldrM step acc m = D.foldrM step acc $ D.fromStreamK (toStream m)
386− let stop = return acc
387− single a = step a acc
388− yieldk a r = go r >>= step a
389− in (K.unStream m1) Nothing stop single yieldk
391-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
382-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
392-- user supplied extraction function (the third argument) at each step. This is
383-- user supplied extraction function (the third argument) at each step. This is
@@ -397,7 +388,7 @@ foldrM step acc m = go (toStream m)
397{-# INLINE scanx #-}
388{-# INLINE scanx #-}
398scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
389scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
399scanx step begin done m =
390scanx step begin done m =
400− cons (done begin) $ fromStream $ go (toStream m) begin
391+ K.cons (done begin) $ fromStream $ go (toStream m) begin
402 go m1 !acc = K.Stream $ \_ stp sng yld ->
393 go m1 !acc = K.Stream $ \_ stp sng yld ->
403 let single a = sng (done $ step acc a)
394 let single a = sng (done $ step acc a)
@@ -430,24 +421,7 @@ scanl' step begin m = scanx step begin id m
430-- @since 0.2.0
421-- @since 0.2.0
431{-# INLINE foldx #-}
422{-# INLINE foldx #-}
432foldx :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
423foldx :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
433−foldx step begin done m = get $ go (toStream m) begin
424+foldx = K.foldx
435− {-# NOINLINE get #-}
437− let single = return . done
438− in (K.unStream m1) Nothing undefined single undefined
440− -- Note, this can be implemented by making a recursive call to "go",
441− -- however that is more expensive because of unnecessary recursion
442− -- that cannot be tail call optimized. Unfolding recursion explicitly via
443− -- continuations is much more efficient.
444− go m1 !acc = K.Stream $ \_ _ sng yld ->
446− single a = sng $ step acc a
448− let stream = go r (step acc a)
449− in (K.unStream stream) Nothing undefined sng yld
450− in (K.unStream m1) Nothing stop single yieldk
453-- @since 0.1.0
427-- @since 0.1.0
@@ -460,20 +434,14 @@ foldl = foldx
460-- @since 0.2.0
434-- @since 0.2.0
461{-# INLINE foldl' #-}
435{-# INLINE foldl' #-}
462foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
436foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
463−foldl' step begin m = foldx step begin id m
437+foldl' step begin m = D.foldl' step begin $ D.fromStreamK (toStream m)
465-- XXX replace the recursive "go" with explicit continuations.
439-- XXX replace the recursive "go" with explicit continuations.
466-- | Like 'foldx', but with a monadic step function.
440-- | Like 'foldx', but with a monadic step function.
468-- @since 0.2.0
442-- @since 0.2.0
469foldxM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
443foldxM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
470−foldxM step begin done m = go begin (toStream m)
444+foldxM = K.foldxM
473− let stop = acc >>= done
474− single a = acc >>= \b -> step b a >>= done
475− yieldk a r = acc >>= \b -> go (step b a) r
476− in (K.unStream m1) Nothing stop single yieldk
479-- @since 0.1.0
447-- @since 0.1.0
@@ -485,7 +453,7 @@ foldlM = foldxM
486-- @since 0.2.0
454-- @since 0.2.0
487foldlM' :: Monad m => (b -> a -> m b) -> b -> SerialT m a -> m b
455foldlM' :: Monad m => (b -> a -> m b) -> b -> SerialT m a -> m b
488−foldlM' step begin m = foldxM step (return begin) return m
456+foldlM' step begin m = D.foldlM' step begin $ D.fromStreamK (toStream m)
490-- | Decompose a stream into its head and tail. If the stream is empty, returns
458-- | Decompose a stream into its head and tail. If the stream is empty, returns
491-- 'Nothing'. If the stream is non-empty, returns @Just (a, ma)@, where @a@ is
459-- 'Nothing'. If the stream is non-empty, returns @Just (a, ma)@, where @a@ is
@@ -495,7 +463,7 @@ foldlM' step begin m = foldxM step (return begin) return m
495uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
463uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
496uncons m =
464uncons m =
497 let stop = return Nothing
465 let stop = return Nothing
498− single a = return (Just (a, nil))
466+ single a = return (Just (a, K.nil))
499 yieldk a r = return (Just (a, fromStream r))
467 yieldk a r = return (Just (a, fromStream r))
500 in (K.unStream (toStream m)) Nothing stop single yieldk
468 in (K.unStream (toStream m)) Nothing stop single yieldk
@@ -518,9 +486,9 @@ toHandle h m = go (toStream m)
518-- | Convert a stream into a list in the underlying monad.
486-- | Convert a stream into a list in the underlying monad.
520-- @since 0.1.0
488-- @since 0.1.0
521−{-# INLINABLE toList #-}
489+{-# INLINE toList #-}
522toList :: Monad m => SerialT m a -> m [a]
490toList :: Monad m => SerialT m a -> m [a]
523−toList = foldrM (\a xs -> return (a : xs)) []
491+toList m = D.toList $ D.fromStreamK (toStream m)
525-- | Take first 'n' elements from the stream and discard the rest.
493-- | Take first 'n' elements from the stream and discard the rest.
@@ -644,7 +612,7 @@ head m =
644tail :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
612tail :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
646 let stop = return Nothing
614 let stop = return Nothing
647− single _ = return $ Just nil
615+ single _ = return $ Just K.nil
648 yieldk _ r = return $ Just $ fromStream r
616 yieldk _ r = return $ Just $ fromStream r
649 in (K.unStream (toStream m)) Nothing stop single yieldk
617 in (K.unStream (toStream m)) Nothing stop single yieldk
@@ -653,7 +621,7 @@ tail m =
653-- @since 0.1.1
621-- @since 0.1.1
654{-# INLINE last #-}
622{-# INLINE last #-}
655last :: Monad m => SerialT m a -> m (Maybe a)
623last :: Monad m => SerialT m a -> m (Maybe a)
656−last = foldl (\_ y -> Just y) Nothing id
624+last m = D.last $ D.fromStreamK (toStream m)
658-- | Determine whether the stream is empty.
626-- | Determine whether the stream is empty.
@@ -761,14 +729,14 @@ maximum m = go Nothing (toStream m)
761-- /Concurrent (do not use with 'parallely' on infinite streams)/
729-- /Concurrent (do not use with 'parallely' on infinite streams)/
763-- @since 0.1.0
731-- @since 0.1.0
764−{-# INLINE mapM #-}
732+{-# INLINE_EARLY mapM #-}
765mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
733mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
766−mapM f m = go (toStream m)
734+mapM = K.mapM
768− go m1 = fromStream $ K.Stream $ \svr stp sng yld ->
736+{-# RULES "mapM serial" mapM = mapMSerial #-}
769− let single a = f a >>= sng
737+{-# INLINE mapMSerial #-}
770− yieldk a r = K.unStream (toStream (f a |: (go r))) svr stp sng yld
738+mapMSerial :: Monad m => (a -> m b) -> SerialT m a -> SerialT m b
771− in (K.unStream m1) Nothing stp single yieldk
739+mapMSerial = Serial.mapM
773-- | Map a 'Maybe' returning function to a stream, filter out the 'Nothing'
741-- | Map a 'Maybe' returning function to a stream, filter out the 'Nothing'
774-- elements, and return a stream of values extracted from 'Just'.
742-- elements, and return a stream of values extracted from 'Just'.
@@ -802,14 +770,9 @@ mapMaybeM f = fmap fromJust . filter isJust . mapM f
802-- output of the action.
770-- output of the action.
804-- @since 0.1.0
772-- @since 0.1.0
805mapM_ :: Monad m => (a -> m b) -> SerialT m a -> m ()
774mapM_ :: Monad m => (a -> m b) -> SerialT m a -> m ()
806−mapM_ f m = go (toStream m)
775+mapM_ f m = D.mapM_ f $ D.fromStreamK (toStream m)
809− let stop = return ()
810− single a = void (f a)
811− yieldk a r = f a >> go r
812− in (K.unStream m1) Nothing stop single yieldk
814-- | Reduce a stream of monadic actions to a stream of the output of those
777-- | Reduce a stream of monadic actions to a stream of the output of those
815-- actions.
778-- actions.