@@ -133,8 +133,6 @@ module Streamly.Internal.Prelude
134 -- * Transformation
134 -- * Transformation
135 , transform
135 , transform
139 -- ** Mapping
137 -- ** Mapping
140 , Serial.map
138 , Serial.map
@@ -376,6 +374,17 @@ module Streamly.Internal.Prelude
376 , finally
374 , finally
377+ -- * Generalize Inner Monad
381+ -- * Transform Inner Monad
379 -- * Diagnostics
388 -- * Diagnostics
380 , inspectMode
389 , inspectMode
@@ -399,6 +408,8 @@ import Control.Exception (Exception)
399import Control.Monad (void)
408import Control.Monad (void)
400import Control.Monad.Catch (MonadCatch)
409import Control.Monad.Catch (MonadCatch)
401import Control.Monad.IO.Class (MonadIO(..))
410import Control.Monad.IO.Class (MonadIO(..))
411+import Control.Monad.Reader (ReaderT)
412+import Control.Monad.State.Strict (StateT)
402import Control.Monad.Trans (MonadTrans(..))
413import Control.Monad.Trans (MonadTrans(..))
403import Data.Functor.Identity (Identity (..))
414import Data.Functor.Identity (Identity (..))
404import Data.Heap (Entry(..))
415import Data.Heap (Entry(..))
@@ -1471,15 +1482,6 @@ toPureRev = foldl' (flip K.cons) K.nil
1471transform :: (IsStream t, Monad m) => Pipe m a b -> t m a -> t m b
1482transform :: (IsStream t, Monad m) => Pipe m a b -> t m a -> t m b
1472transform pipe xs = fromStreamD $ D.transform pipe (toStreamD xs)
1483transform pipe xs = fromStreamD $ D.transform pipe (toStreamD xs)
1474−{-# INLINE hoist #-}
1475−hoist :: (Monad m, Monad n)
1476− => (forall x. m x -> n x) -> SerialT m a -> SerialT n a
1477−hoist f xs = fromStreamS $ S.hoist f (toStreamS xs)
1479−{-# INLINE generally #-}
1480−generally :: (IsStream t, Monad m) => t Identity a -> t m a
1481−generally xs = fromStreamS $ S.hoist (return . runIdentity) (toStreamS xs)
1483------------------------------------------------------------------------------
1485------------------------------------------------------------------------------
1484-- Transformation by Folding (Scans)
1486-- Transformation by Folding (Scans)
1485------------------------------------------------------------------------------
1487------------------------------------------------------------------------------
@@ -3696,3 +3698,84 @@ handle :: (IsStream t, MonadCatch m, Exception e)
3696 => (e -> t m a) -> t m a -> t m a
3698 => (e -> t m a) -> t m a -> t m a
3697handle handler xs =
3699handle handler xs =
3698 D.fromStreamD $ D.handle (\e -> D.toStreamD $ handler e) $ D.toStreamD xs
3700 D.fromStreamD $ D.handle (\e -> D.toStreamD $ handler e) $ D.toStreamD xs
3702+------------------------------------------------------------------------------
3703+-- Generalize the underlying monad
3704+------------------------------------------------------------------------------
3706+-- | Transform the inner monad of a stream using a natural transformation.
3710+{-# INLINE hoist #-}
3711+hoist :: (Monad m, Monad n)
3712+ => (forall x. m x -> n x) -> SerialT m a -> SerialT n a
3713+hoist f xs = fromStreamS $ S.hoist f (toStreamS xs)
3715+-- | Generalize the inner monad of the stream from 'Identity' to any monad.
3719+{-# INLINE generally #-}
3720+generally :: (IsStream t, Monad m) => t Identity a -> t m a
3721+generally xs = fromStreamS $ S.hoist (return . runIdentity) (toStreamS xs)
3723+------------------------------------------------------------------------------
3724+-- Add and remove a monad transformer
3725+------------------------------------------------------------------------------
3727+-- | Lift the inner monad of a stream using a monad transformer.
3731+{-# INLINE liftInner #-}
3732+liftInner :: (Monad m, IsStream t, MonadTrans tr, Monad (tr m))
3733+ => t m a -> t (tr m) a
3734+liftInner xs = fromStreamD $ D.liftInner (toStreamD xs)
3736+-- | Evaluate the inner monad of a stream as 'ReaderT'.
3740+{-# INLINE runReaderT #-}
3741+runReaderT :: (IsStream t, Monad m) => s -> t (ReaderT s m) a -> t m a
3742+runReaderT s xs = fromStreamD $ D.runReaderT s (toStreamD xs)
3744+-- | Evaluate the inner monad of a stream as 'StateT'.
3746+-- This is supported only for 'SerialT' as concurrent state updation may not be
3751+{-# INLINE evalStateT #-}
3752+evalStateT :: Monad m => s -> SerialT (StateT s m) a -> SerialT m a
3753+evalStateT s xs = fromStreamD $ D.evalStateT s (toStreamD xs)
3755+-- | Run a stateful (StateT) stream transformation using a given state.
3757+-- This is supported only for 'SerialT' as concurrent state updation may not be
3762+{-# INLINE usingStateT #-}
3766+ -> (SerialT (StateT s m) a -> SerialT (StateT s m) a)
3769+usingStateT s f xs = evalStateT s $ f $ liftInner xs
3771+-- | Evaluate the inner monad of a stream as 'StateT' and emit the resulting
3772+-- state and value pair after each step.
3774+-- This is supported only for 'SerialT' as concurrent state updation may not be
3779+{-# INLINE runStateT #-}
3780+runStateT :: Monad m => s -> SerialT (StateT s m) a -> SerialT m (s, a)
3781+runStateT s xs = fromStreamD $ D.runStateT s (toStreamD xs)