@@ -87,6 +87,7 @@ import Streamly.Internal.Data.Stream.Serial (SerialT(..))
8787import Streamly.Internal.Data.Unfold.Type (Unfold(..))
8888import Streamly.Internal.System.IO (unsafeInlineIO)
8989
90+import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
9091import qualified Streamly.Internal.Data.Array.Foreign.Type as A
9192
9293import Prelude hiding (length, concat, read)
@@ -513,23 +514,12 @@ unsafeFoldRingNM count rh f z rb@Ring {..} =
513514
514515data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Show
515516
516−-- | @slidingWindow collector@ is an incremental sliding window
517−-- fold that does not require all the intermediate elements in a computation.
518−-- This maintains n elements in the window, when a new element comes it slides
519−-- out the oldest element and the new element along with the old element are
520−-- supplied to the collector fold.
521−--
522−-- The Maybe is for the case when initially the window is filling and
523−-- there is no old element.
524−--
525−{-# INLINE slidingWindow #-}
526−slidingWindow :: forall m a b. (MonadIO m, Storable a)
527− => Int -> Fold m (a, Maybe a) b -> Fold m a b
528−slidingWindow n f = slidingWindowWith n (lmap fst f)
529−
517+-- | IMPORTANT NOTE: The ring is mutable, therefore, the result of @(m (Array
518+-- a))@ action depends on when it is executed. It does not capture the sanpshot
519+-- of the ring at a particular time.
530520{-# INLINE slidingWindowWith #-}
531521slidingWindowWith :: forall m a b. (MonadIO m, Storable a)
532− => Int -> Fold m ((a, Maybe a), (Ring a, Ptr a, Int)) b -> Fold m a b
522+ => Int -> Fold m ((a, Maybe a), (m (Array a))) b -> Fold m a b
533523slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
534524
535525 where
@@ -545,11 +535,16 @@ slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
545535 Partial s -> Partial $ Tuple4' rb rh (0 :: Int) s
546536 Done b -> Done b
547537
538+ toArray foldRing rb rh = do
539+ arr <- liftIO $ MA.newArray n
540+ let snoc' b a = liftIO $ MA.snocUnsafe b a
541+ foldRing rh snoc' arr rb
542+
548543 step (Tuple4' rb rh i st) a
549544 | i < n = do
550545 rh1 <- liftIO $ unsafeInsert rb rh a
551546 liftIO $ touchForeignPtr (ringStart rb)
552− r <- step1 st ((a, Nothing), (rb, rh1, i + 1))
547+ r <- step1 st ((a, Nothing), toArray unsafeFoldRingM rb rh)
553548 return $
554549 case r of
555550 Partial s -> Partial $ Tuple4' rb rh1 (i + 1) s
@@ -558,10 +553,24 @@ slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
558553 old <- liftIO $ peek rh
559554 rh1 <- liftIO $ unsafeInsert rb rh a
560555 liftIO $ touchForeignPtr (ringStart rb)
561− r <- step1 st ((a, Just old),(rb, rh1, n) )
556+ r <- step1 st ((a, Just old), toArray unsafeFoldRingFullM rb rh)
562557 return $
563558 case r of
564559 Partial s -> Partial $ Tuple4' rb rh1 (i + 1) s
565560 Done b -> Done b
566561
567562 extract (Tuple4' _ _ _ st) = extract1 st
563+
564+-- | @slidingWindow collector@ is an incremental sliding window
565+-- fold that does not require all the intermediate elements in a computation.
566+-- This maintains @n@ elements in the window, when a new element comes it slides
567+-- out the oldest element and the new element along with the old element are
568+-- supplied to the collector fold.
569+--
570+-- The 'Maybe' type is for the case when initially the window is filling and
571+-- there is no old element.
572+--
573+{-# INLINE slidingWindow #-}
574+slidingWindow :: forall m a b. (MonadIO m, Storable a)
575+ => Int -> Fold m (a, Maybe a) b -> Fold m a b
576+slidingWindow n f = slidingWindowWith n (lmap fst f)