@@ -410,6 +410,10 @@ module Streamly.Internal.Data.Fold.Type
411 , isClosed
411 , isClosed
413+ -- * Lifting inner monad
413 -- * Deprecated
417 -- * Deprecated
415 , serialWith
419 , serialWith
@@ -422,6 +426,7 @@ import Control.Applicative (liftA2)
422import Control.Monad ((>=>))
426import Control.Monad ((>=>))
423import Data.Bifunctor (Bifunctor(..))
427import Data.Bifunctor (Bifunctor(..))
424import Data.Either (fromLeft, fromRight, isLeft, isRight)
428import Data.Either (fromLeft, fromRight, isLeft, isRight)
429+import Data.Functor.Identity (Identity(..))
425import Fusion.Plugin.Types (Fuse(..))
430import Fusion.Plugin.Types (Fuse(..))
426import Streamly.Internal.Data.Fold.Step (Step(..), mapMStep, chainStepM)
431import Streamly.Internal.Data.Fold.Step (Step(..), mapMStep, chainStepM)
427import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
432import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
@@ -1817,3 +1822,22 @@ refoldMany1 (Refold sstep sinject sextract) (Fold cstep cinitial cextract) =
1817refold :: Monad m => Refold m b a c -> Fold m a b -> Fold m a c
1822refold :: Monad m => Refold m b a c -> Fold m a b -> Fold m a c
1818refold (Refold step inject extract) f =
1823refold (Refold step inject extract) f =
1819 Fold step (extractM f >>= inject) extract
1824 Fold step (extractM f >>= inject) extract
1826+------------------------------------------------------------------------------
1828+------------------------------------------------------------------------------
1830+-- | Change the underlying monad of a fold
1833+hoist :: (forall x. m x -> n x) -> Fold m a b -> Fold n a b
1834+hoist f (Fold step initial extract) =
1835+ Fold (\x a -> f $ step x a) (f initial) (f . extract)
1837+-- | Adapt a pure fold to any monad
1839+-- >>> generally = Fold.hoist (return . runIdentity)
1842+generally :: Monad m => Fold Identity a b -> Fold m a b
1843+generally = hoist (return . runIdentity)