@@ -94,6 +94,11 @@ import Streamly.Internal.Data.Time.Clock
9494import Streamly.Internal.Data.Time.Units
9595 (toAbsTime, AbsTime, toRelTime64, RelTime64)
9696
97+#ifdef USE_UNFOLDS_EVERYWHERE
98+import qualified Streamly.Internal.Data.Unfold as Unfold
99+import qualified Streamly.Internal.Data.Unfold.Enumeration as Unfold
100+#endif
101+
97102import Prelude hiding (iterate, repeat, replicate, takeWhile)
98103import Streamly.Internal.Data.Stream.StreamD.Type
99104
@@ -131,6 +136,9 @@ cons x (Stream step state) = Stream step1 Nothing
131136-- Adapted from vector package
132137{-# INLINE_NORMAL unfoldrM #-}
133138unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
139+#ifdef USE_UNFOLDS_EVERYWHERE
140+unfoldrM next = unfold (Unfold.unfoldrM next)
141+#else
134142unfoldrM next = Stream step
135143 where
136144 {-# INLINE_LATE step #-}
@@ -139,6 +147,7 @@ unfoldrM next = Stream step
139147 return $ case r of
140148 Just (x, s) -> Yield x s
141149 Nothing -> Stop
150+#endif
142151
143152{-# INLINE_LATE unfoldr #-}
144153unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
@@ -150,15 +159,26 @@ unfoldr f = unfoldrM (return . f)
150159
151160{-# INLINE_NORMAL repeatM #-}
152161repeatM :: Monad m => m a -> Stream m a
162+#ifdef USE_UNFOLDS_EVERYWHERE
163+repeatM = unfold Unfold.repeatM
164+#else
153165repeatM x = Stream (\_ _ -> x >>= \r -> return $ Yield r ()) ()
166+#endif
154167
155168{-# INLINE_NORMAL repeat #-}
156169repeat :: Monad m => a -> Stream m a
170+#ifdef USE_UNFOLDS_EVERYWHERE
171+repeat x = repeatM (pure x)
172+#else
157173repeat x = Stream (\_ _ -> return $ Yield x ()) ()
174+#endif
158175
159176-- Adapted from the vector package
160177{-# INLINE_NORMAL replicateM #-}
161178replicateM :: forall m a. Monad m => Int -> m a -> Stream m a
179+#ifdef USE_UNFOLDS_EVERYWHERE
180+replicateM n = unfold (Unfold.replicateM n)
181+#else
162182replicateM n p = Stream step n
163183 where
164184 {-# INLINE_LATE step #-}
@@ -167,6 +187,7 @@ replicateM n p = Stream step n
167187 | otherwise = do
168188 x <- p
169189 return $ Yield x (i - 1)
190+#endif
170191
171192{-# INLINE_NORMAL replicate #-}
172193replicate :: Monad m => Int -> a -> Stream m a
@@ -189,10 +210,15 @@ replicate n x = replicateM n (return x)
189210-- enumerateFromStepIntegral is faster for integrals.
190211{-# INLINE_NORMAL enumerateFromStepNum #-}
191212enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
213+#ifdef USE_UNFOLDS_EVERYWHERE
214+enumerateFromStepNum from stride =
215+ unfold Unfold.enumerateFromStepNum (from, stride)
216+#else
192217enumerateFromStepNum from stride = Stream step 0
193218 where
194219 {-# INLINE_LATE step #-}
195220 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
221+#endif
196222
197223{-# INLINE_NORMAL enumerateFromNum #-}
198224enumerateFromNum :: (Monad m, Num a) => a -> Stream m a
@@ -206,6 +232,7 @@ enumerateFromThenNum from next = enumerateFromStepNum from (next - from)
206232-- Enumeration of Integrals
207233------------------------------------------------------------------------------
208234
235+#ifndef USE_UNFOLDS_EVERYWHERE
209236data EnumState a = EnumInit | EnumYield a a a | EnumStop
210237
211238{-# INLINE_NORMAL enumerateFromThenToIntegralUp #-}
@@ -256,6 +283,7 @@ enumerateFromThenToIntegralDn from next to = Stream step EnumInit
256283 else Yield x $ EnumYield (x + stride) stride toMinus
257284
258285 step _ EnumStop = return Stop
286+#endif
259287
260288-- XXX This can perhaps be simplified and written in terms of
261289-- enumeratFromStepIntegral as we have done in unfolds. But anyway we should be
@@ -264,29 +292,44 @@ enumerateFromThenToIntegralDn from next to = Stream step EnumInit
264292enumerateFromThenToIntegral
265293 :: (Monad m, Integral a)
266294 => a -> a -> a -> Stream m a
295+#ifdef USE_UNFOLDS_EVERYWHERE
296+enumerateFromThenToIntegral from next to =
297+ unfold Unfold.enumerateFromThenToIntegral (from, next, to)
298+#else
267299enumerateFromThenToIntegral from next to
268300 | next >= from = enumerateFromThenToIntegralUp from next to
269301 | otherwise = enumerateFromThenToIntegralDn from next to
302+#endif
270303
271304{-# INLINE_NORMAL enumerateFromThenIntegral #-}
272305enumerateFromThenIntegral
273306 :: (Monad m, Integral a, Bounded a)
274307 => a -> a -> Stream m a
308+#ifdef USE_UNFOLDS_EVERYWHERE
309+enumerateFromThenIntegral from next =
310+ unfold Unfold.enumerateFromThenIntegralBounded (from, next)
311+#else
275312enumerateFromThenIntegral from next =
276313 if next > from
277314 then enumerateFromThenToIntegralUp from next maxBound
278315 else enumerateFromThenToIntegralDn from next minBound
316+#endif
279317
280318-- | Can be used to enumerate unbounded integrals. This does not check for
281319-- overflow or underflow for bounded integrals.
282320--
283321{-# INLINE_NORMAL enumerateFromStepIntegral #-}
284322enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
323+#ifdef USE_UNFOLDS_EVERYWHERE
324+enumerateFromStepIntegral from stride =
325+ unfold Unfold.enumerateFromStepIntegral (from, stride)
326+#else
285327enumerateFromStepIntegral from stride =
286328 from `seq` stride `seq` Stream step from
287329 where
288330 {-# INLINE_LATE step #-}
289331 step _ !x = return $ Yield x $! (x + stride)
332+#endif
290333
291334-- | Enumerate upwards from @from@ to @to@. We are assuming that "to" is
292335-- constrained by the type to be within max/min bounds.
@@ -353,12 +396,16 @@ times g = Stream step Nothing
353396
354397{-# INLINE_NORMAL fromIndicesM #-}
355398fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
399+#ifdef USE_UNFOLDS_EVERYWHERE
400+fromIndicesM gen = unfold (Unfold.fromIndicesM gen) 0
401+#else
356402fromIndicesM gen = Stream step 0
357403 where
358404 {-# INLINE_LATE step #-}
359405 step _ i = do
360406 x <- gen i
361407 return $ Yield x (i + 1)
408+#endif
362409
363410{-# INLINE fromIndices #-}
364411fromIndices :: Monad m => (Int -> a) -> Stream m a
@@ -385,7 +432,11 @@ generate n gen = generateM n (return . gen)
385432
386433{-# INLINE_NORMAL iterateM #-}
387434iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
435+#ifdef USE_UNFOLDS_EVERYWHERE
436+iterateM step = unfold (Unfold.iterateM step)
437+#else
388438iterateM step = Stream (\_ st -> st >>= \(!x) -> return $ Yield x (step x))
439+#endif
389440
390441{-# INLINE_NORMAL iterate #-}
391442iterate :: Monad m => (a -> a) -> a -> Stream m a
@@ -399,8 +450,12 @@ iterate step st = iterateM (return . step) (return st)
399450-- | Convert a list of monadic actions to a 'Stream'
400451{-# INLINE_LATE fromListM #-}
401452fromListM :: MonadAsync m => [m a] -> Stream m a
453+#ifdef USE_UNFOLDS_EVERYWHERE
454+fromListM = unfold Unfold.fromListM
455+#else
402456fromListM = Stream step
403457 where
404458 {-# INLINE_LATE step #-}
405459 step _ (m:ms) = m >>= \x -> return $ Yield x ms
406460 step _ [] = return Stop
461+#endif