@@ -71,6 +71,9 @@ module Streamly.Internal.Data.Unfold
73 -- * Unfolds
73 -- * Unfolds
74 , singleton
77 , singleton
75 , replicateM
78 , replicateM
76 , fromList
79 , fromList
@@ -118,6 +121,8 @@ import Streamly.Internal.Data.SVar (defState)
118import Control.Monad.Catch (MonadCatch)
121import Control.Monad.Catch (MonadCatch)
120import qualified Control.Monad.Catch as MC
123import qualified Control.Monad.Catch as MC
124+import qualified Streamly.Streams.StreamK as K
125+import qualified Streamly.Streams.StreamD as D
122-------------------------------------------------------------------------------
127-------------------------------------------------------------------------------
123-- Input operations
128-- Input operations
@@ -195,6 +200,43 @@ map f (Unfold ustep uinject) = Unfold step uinject
195 Skip s -> Skip s
200 Skip s -> Skip s
196 Stop -> Stop
201 Stop -> Stop
203+-------------------------------------------------------------------------------
204+-- Convert streams into unfolds
205+-------------------------------------------------------------------------------
207+{-# INLINE_LATE streamStep #-}
208+streamStep :: Monad m => Stream m a -> m (Step (Stream m a) a)
209+streamStep (Stream step1 state) = do
210+ r <- step1 defState state
212+ Yield x s -> Yield x (Stream step1 s)
213+ Skip s -> Skip (Stream step1 s)
216+-- | Convert a stream into an 'Unfold'. Note that a stream converted to an
217+-- 'Unfold' may not be as efficient as an 'Unfold' in some situations.
220+fromStream :: (K.IsStream t, Monad m) => t m b -> Unfold m Void b
221+fromStream str = Unfold streamStep (\_ -> return $ D.toStreamD str)
223+-- | Convert a single argument stream generator function into an
224+-- 'Unfold'. Note that a stream converted to an 'Unfold' may not be as
225+-- efficient as an 'Unfold' in some situations.
228+fromStream1 :: (K.IsStream t, Monad m) => (a -> t m b) -> Unfold m a b
229+fromStream1 f = Unfold streamStep (return . D.toStreamD . f)
231+-- | Convert a two argument stream generator function into an 'Unfold'. Note
232+-- that a stream converted to an 'Unfold' may not be as efficient as an
233+-- 'Unfold' in some situations.
236+fromStream2 :: (K.IsStream t, Monad m)
237+ => (a -> b -> t m c) -> Unfold m (a, b) c
238+fromStream2 f = Unfold streamStep (\(a, b) -> return $ D.toStreamD $ f a b)
198-------------------------------------------------------------------------------
240-------------------------------------------------------------------------------
199-- Unfolds
241-- Unfolds
200-------------------------------------------------------------------------------
242-------------------------------------------------------------------------------