@@ -66,6 +66,7 @@ module Streamly.Internal.Data.Fold
6666 -- ** Collectors
6767 , toList
6868 , toListRevF -- experimental
69+ -- $toListRevF
6970 , toParallelSVar
7071
7172 -- * Terminating Folds
@@ -224,6 +225,7 @@ where
224225
225226import Control.Monad (void, join)
226227import Control.Monad.IO.Class (MonadIO(..))
228+import Data.Bifunctor (first)
227229import Data.Functor.Identity (Identity(..))
228230import Data.Int (Int64)
229231import Data.Map.Strict (Map)
@@ -235,6 +237,8 @@ import Streamly.Internal.Data.Either.Strict (Either'(..))
235237import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
236238import Streamly.Internal.Data.Pipe.Types (Pipe (..), PipeState(..))
237239import Streamly.Internal.Data.Tuple.Strict (Tuple'(..), Tuple3'(..))
240+import Streamly.Internal.Data.Either.Strict
241+ (fromLeft', fromRight', isLeft', isRight')
238242
239243import qualified Data.Map.Strict as Map
240244import qualified Streamly.Internal.Data.Fold.Types as FL
@@ -265,7 +269,7 @@ mkAccum :: Monad m => (s -> a -> s) -> s -> (s -> b) -> Fold m a b
265269mkAccum step initial extract =
266270 Fold
267271 (\s a -> return $ Partial $ step s a)
268− (return initial)
272+ (return (Partial initial))
269273 (return . extract)
270274
271275-- | Similar to 'mkAccum' but the final state extracted is identical to the
@@ -284,7 +288,8 @@ mkAccum_ step initial = mkAccum step initial id
284288--
285289{-# INLINE mkAccumM #-}
286290mkAccumM :: Functor m => (s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
287−mkAccumM step = Fold (\s a -> Partial <$> step s a)
291+mkAccumM step initial =
292+ Fold (\s a -> Partial <$> step s a) (Partial <$> initial)
288293
289294-- | Similar to 'mkAccumM' but the final state extracted is identical to the
290295-- intermediate state.
@@ -301,7 +306,7 @@ mkAccumM_ step initial = mkAccumM step initial return
301306-- /Internal/
302307--
303308{-# INLINE mkFold #-}
304−mkFold :: Monad m => (s -> a -> Step s b) -> s -> (s -> b) -> Fold m a b
309+mkFold :: Monad m => (s -> a -> Step s b) -> Step s b -> (s -> b) -> Fold m a b
305310mkFold step initial extract =
306311 Fold (\s a -> return $ step s a) (return initial) (return . extract)
307312
@@ -311,7 +316,7 @@ mkFold step initial extract =
311316-- /Internal/
312317--
313318{-# INLINE mkFold_ #-}
314−mkFold_ :: Monad m => (b -> a -> Step b b) -> b -> Fold m a b
319+mkFold_ :: Monad m => (b -> a -> Step b b) -> Step b b -> Fold m a b
315320mkFold_ step initial = mkFold step initial id
316321
317322-- | Make a terminating fold with an effectful step function and initial state,
@@ -324,7 +329,7 @@ mkFold_ step initial = mkFold step initial id
324329-- /Internal/
325330--
326331{-# INLINE mkFoldM #-}
327−mkFoldM :: (s -> a -> m (Step s b)) -> m s -> (s -> m b) -> Fold m a b
332+mkFoldM :: (s -> a -> m (Step s b)) -> m (Step s b) -> (s -> m b) -> Fold m a b
328333mkFoldM = Fold
329334
330335-- | Similar to 'mkFoldM' but the final state extracted is identical to the
@@ -333,8 +338,8 @@ mkFoldM = Fold
333338-- /Internal/
334339--
335340{-# INLINE mkFoldM_ #-}
336−mkFoldM_ :: Monad m => (b -> a -> m (Step b b)) -> m b -> Fold m a b
337−mkFoldM_ step initial = Fold step initial return
341+mkFoldM_ :: Monad m => (b -> a -> m (Step b b)) -> m (Step b b) -> Fold m a b
342+mkFoldM_ step initial = mkFoldM step initial return
338343
339344------------------------------------------------------------------------------
340345-- hoist
@@ -364,16 +369,19 @@ generally = hoist (return . runIdentity)
364369-- @since 0.7.0
365370{-# INLINE sequence #-}
366371sequence :: Monad m => Fold m a (m b) -> Fold m a b
367−sequence (Fold step initial extract) = Fold step' initial extract'
372+sequence (Fold step initial extract) = Fold step' initial1 extract'
368373
369374 where
370375
371− step' s a = do
372− res <- step s a
376+ eval res =
373377 case res of
374378 Partial x -> return $ Partial x
375379 Done b -> Done <$> b
376380
381+ initial1 = initial >>= eval
382+
383+ step' s a = step s a >>= eval
384+
377385 extract' = join . extract
378386
379387-- | Map a monadic function on the output of a fold.
@@ -413,7 +421,7 @@ transform (Pipe pstep1 pstep2 pinitial) (Fold fstep finitial fextract) =
413421
414422 where
415423
416− initial = Tuple' pinitial <$> finitial
424+ initial = first (Tuple' pinitial) <$> finitial
417425
418426 step (Tuple' ps fs) x = do
419427 r <- pstep1 ps x
@@ -452,12 +460,12 @@ transform (Pipe pstep1 pstep2 pinitial) (Fold fstep finitial fextract) =
452460-- from the 'Foldable', the result is 'None' for empty containers.
453461{-# INLINABLE _Fold1 #-}
454462_Fold1 :: Monad m => (a -> a -> a) -> Fold m a (Maybe a)
455−_Fold1 step = Fold step_ (return Nothing') (return . toMaybe)
463+_Fold1 step = mkAccum step_ Nothing' toMaybe
456464
457465 where
458466
459− step_ Nothing' a = return $ Partial $ Just' a
460− step_ (Just' x) a = return $ Partial $ Just' $ step x a
467+ step_ Nothing' a = Just' a
468+ step_ (Just' x) a = Just' $ step x a
461469
462470------------------------------------------------------------------------------
463471-- Left folds
@@ -475,15 +483,7 @@ _Fold1 step = Fold step_ (return Nothing') (return . toMaybe)
475483-- @since 0.7.0
476484{-# INLINABLE drain #-}
477485drain :: Monad m => Fold m a ()
478−drain = Fold step begin done
479−
480− where
481−
482− begin = return ()
483−
484− step _ _ = return $ FL.Partial ()
485−
486− done = return
486+drain = mkAccum_ (\_ _ -> ()) ()
487487
488488-- |
489489-- > drainBy f = lmapM f drain
@@ -495,7 +495,7 @@ drain = Fold step begin done
495495-- @since 0.7.0
496496{-# INLINABLE drainBy #-}
497497drainBy :: Monad m => (a -> m b) -> Fold m a ()
498−drainBy f = Fold (const (fmap FL.Partial . void . f)) (return ()) return
498+drainBy f = lmapM f drain
499499
500500{-# INLINABLE drainBy2 #-}
501501drainBy2 :: Monad m => (a -> m b) -> Fold2 m c a ()
@@ -521,7 +521,7 @@ last = _Fold1 (\_ x -> x)
521521-- @since 0.7.0
522522{-# INLINE genericLength #-}
523523genericLength :: (Monad m, Num b) => Fold m a b
524−genericLength = Fold (\n _ -> return $ Partial $ n + 1) (return 0) return
524+genericLength = mkAccum_ (\n _ -> n + 1) 0
525525
526526-- | Determine the length of the input stream.
527527--
@@ -541,7 +541,7 @@ length = genericLength
541541-- @since 0.7.0
542542{-# INLINE sum #-}
543543sum :: (Monad m, Num a) => Fold m a a
544−sum = Fold (\x a -> return $ Partial $ x + a) (return 0) return
544+sum = mkAccum_ (+) 0
545545
546546-- | Determine the product of all elements of a stream of numbers. Returns
547547-- multiplicative identity (@1@) when the stream is empty. The fold terminates
@@ -553,15 +553,14 @@ sum = Fold (\x a -> return $ Partial $ x + a) (return 0) return
553553-- /Since 0.8.0 (Added 'Eq' constraint)/
554554{-# INLINE product #-}
555555product :: (Monad m, Num a, Eq a) => Fold m a a
556−product = Fold step (return 1) return
556+product = mkFold_ step (Partial 1)
557557
558558 where
559559
560560 step x a =
561− return
562− $ if a == 0
563− then Done 0
564− else Partial $ x * a
561+ if a == 0
562+ then Done 0
563+ else Partial $ x * a
565564
566565------------------------------------------------------------------------------
567566-- To Summary (Maybe)
@@ -634,16 +633,15 @@ minimum = _Fold1 min
634633-- @since 0.7.0
635634{-# INLINABLE mean #-}
636635mean :: (Monad m, Fractional a) => Fold m a a
637−mean = Fold step (return begin) (return . done)
636+mean = mkAccum step begin done
638637
639638 where
640639
641640 begin = Tuple' 0 0
642641
643642 step (Tuple' x n) y =
644− return
645− $ let n' = n + 1
646− in Partial $ Tuple' (x + (y - x) / n') n'
643+ let n1 = n + 1
644+ in Tuple' (x + (y - x) / n1) n1
647645
648646 done (Tuple' x _) = x
649647
@@ -653,13 +651,13 @@ mean = Fold step (return begin) (return . done)
653651-- @since 0.7.0
654652{-# INLINABLE variance #-}
655653variance :: (Monad m, Fractional a) => Fold m a a
656−variance = Fold step (return begin) (return . done)
654+variance = mkAccum step begin done
657655
658656 where
659657
660658 begin = Tuple3' 0 0 0
661659
662− step (Tuple3' n mean_ m2) x = return $ Partial $ Tuple3' n' mean' m2'
660+ step (Tuple3' n mean_ m2) x = Tuple3' n' mean' m2'
663661
664662 where
665663
@@ -692,17 +690,13 @@ stdDev = sqrt variance
692690-- @since 0.7.0
693691{-# INLINABLE rollingHashWithSalt #-}
694692rollingHashWithSalt :: (Monad m, Enum a) => Int64 -> Fold m a Int64
695−rollingHashWithSalt salt = Fold step initial extract
693+rollingHashWithSalt = mkAccum_ step
696694
697695 where
698696
699697 k = 2891336453 :: Int64
700698
701− initial = return salt
702−
703− step cksum a = return $ Partial $ cksum * k + fromIntegral (fromEnum a)
704−
705− extract = return
699+ step cksum a = cksum * k + fromIntegral (fromEnum a)
706700
707701-- | A default salt used in the implementation of 'rollingHash'.
708702{-# INLINE defaultSalt #-}
@@ -738,7 +732,7 @@ rollingHashFirstN n = ltake n rollingHash
738732--
739733{-# INLINE sconcat #-}
740734sconcat :: (Monad m, Semigroup a) => a -> Fold m a a
741−sconcat i = Fold (\x a -> return $ Partial $ x <> a) (return i) return
735+sconcat = mkAccum_ (<>)
742736
743737-- | Fold an input stream consisting of monoidal elements using 'mappend'
744738-- and 'mempty'.
@@ -783,17 +777,13 @@ foldMap f = lmap f mconcat
783777-- @since 0.7.0
784778{-# INLINABLE foldMapM #-}
785779foldMapM :: (Monad m, Monoid b) => (a -> m b) -> Fold m a b
786−foldMapM act = Fold step begin done
780+foldMapM act = mkAccumM_ step (pure mempty)
787781
788782 where
789783
790− done = return
791−
792− begin = return mempty
793−
794784 step m a = do
795785 m' <- act a
796− return $! Partial $! mappend m m'
786+ return $! mappend m m'
797787
798788------------------------------------------------------------------------------
799789-- To Containers
@@ -810,9 +800,23 @@ foldMapM act = Fold step begin done
810800-- id . (x1 :) . (x2 :) . (x3 :) . ... . (xn :) $ []
811801{-# INLINABLE toList #-}
812802toList :: Monad m => Fold m a [a]
813−toList = Fold (\f x -> return $ Partial $ f . (x :))
814− (return id)
815− (return . ($ []))
803+toList = mkAccum (\f x -> f . (x :)) id ($ [])
804+
805+-- $toListRevF
806+-- This is more efficient than 'Streamly.Internal.Data.Fold.toList'. toList is
807+-- exactly the same as reversing the list after 'toListRevF'.
808+
809+-- | Buffers the input stream to a list in the reverse order of the input.
810+--
811+-- /Warning!/ working on large lists accumulated as buffers in memory could be
812+-- very inefficient, consider using "Streamly.Array" instead.
813+--
814+-- @since 0.7.0
815+
816+-- xn : ... : x2 : x1 : []
817+{-# INLINABLE toListRevF #-}
818+toListRevF :: Monad m => Fold m a [a]
819+toListRevF = mkAccum_ (flip (:)) []
816820
817821------------------------------------------------------------------------------
818822-- Partial Folds
@@ -833,15 +837,14 @@ drainN n = ltake n drain
833837-- @since 0.7.0
834838{-# INLINABLE genericIndex #-}
835839genericIndex :: (Integral i, Monad m) => i -> Fold m a (Maybe a)
836−genericIndex i = Fold step (return 0) (const (return Nothing))
840+genericIndex i = mkFold step (Partial 0) (const Nothing)
837841
838842 where
839843
840844 step j a =
841− return
842− $ if i == j
843− then Done $ Just a
844− else Partial (j + 1)
845+ if i == j
846+ then Done $ Just a
847+ else Partial (j + 1)
845848
846849-- | Lookup the element at the given index.
847850--
@@ -869,15 +872,14 @@ head = _Fold1 const
869872-- @since 0.7.0
870873{-# INLINABLE find #-}
871874find :: Monad m => (a -> Bool) -> Fold m a (Maybe a)
872−find predicate = Fold step (return ()) (const (return Nothing))
875+find predicate = mkFold step (Partial ()) (const Nothing)
873876
874877 where
875878
876879 step () a =
877− return
878− $ if predicate a
879− then Done (Just a)
880− else Partial ()
880+ if predicate a
881+ then Done (Just a)
882+ else Partial ()
881883
882884-- | In a stream of (key-value) pairs @(a, b)@, return the value @b@ of the
883885-- first pair where the key equals the given value @a@.
@@ -887,30 +889,28 @@ find predicate = Fold step (return ()) (const (return Nothing))
887889-- @since 0.7.0
888890{-# INLINABLE lookup #-}
889891lookup :: (Eq a, Monad m) => a -> Fold m (a,b) (Maybe b)
890−lookup a0 = Fold step (return ()) (const (return Nothing))
892+lookup a0 = mkFold step (Partial ()) (const Nothing)
891893
892894 where
893895
894896 step () (a, b) =
895− return
896− $ if a == a0
897− then Done $ Just b
898− else Partial ()
897+ if a == a0
898+ then Done $ Just b
899+ else Partial ()
899900
900901-- | Returns the first index that satisfies the given predicate.
901902--
902903-- @since 0.7.0
903904{-# INLINABLE findIndex #-}
904905findIndex :: Monad m => (a -> Bool) -> Fold m a (Maybe Int)
905−findIndex predicate = Fold step (return 0) (const (return Nothing))
906+findIndex predicate = mkFold step (Partial 0) (const Nothing)
906907
907908 where
908909
909910 step i a =
910− return
911− $ if predicate a
912− then Done $ Just i
913− else Partial (i + 1)
911+ if predicate a
912+ then Done $ Just i
913+ else Partial (i + 1)
914914
915915-- | Returns the first index where a given value is found in the stream.
916916--
@@ -932,7 +932,7 @@ elemIndex a = findIndex (a ==)
932932-- @since 0.7.0
933933{-# INLINABLE null #-}
934934null :: Monad m => Fold m a Bool
935−null = Fold (\() _ -> return $ Done False) (return ()) (\() -> return True)
935+null = mkFold (\() _ -> Done False) (Partial ()) (const True)
936936
937937--
938938-- > any p = lmap p or
@@ -946,17 +946,16 @@ null = Fold (\() _ -> return $ Done False) (return ()) (\() -> return True)
946946-- @since 0.7.0
947947{-# INLINE any #-}
948948any :: Monad m => (a -> Bool) -> Fold m a Bool
949−any predicate = Fold step initial return
949+any predicate = mkFold_ step initial
950950
951951 where
952952
953− initial = return False
953+ initial = Partial False
954954
955955 step _ a =
956− return
957− $ if predicate a
958− then Done True
959− else Partial False
956+ if predicate a
957+ then Done True
958+ else Partial False
960959
961960-- | Return 'True' if the given element is present in the stream.
962961--
@@ -979,17 +978,16 @@ elem a = any (a ==)
979978-- @since 0.7.0
980979{-# INLINABLE all #-}
981980all :: Monad m => (a -> Bool) -> Fold m a Bool
982−all predicate = Fold step initial return
981+all predicate = mkFold_ step initial
983982
984983 where
985984
986− initial = return True
985+ initial = Partial True
987986
988987 step _ a =
989− return
990− $ if predicate a
991− then Partial True
992− else Done False
988+ if predicate a
989+ then Partial True
990+ else Done False
993991
994992-- | Returns 'True' if the given element is not present in the stream.
995993--
@@ -1199,18 +1197,18 @@ sliceEndWith predicate (Fold fstep finitial fextract) =
11991197
12001198 initial = finitial
12011199
1202− step s a =
1200+ step s a = do
1201+ res <- fstep s a
12031202 if not (predicate a)
1204− then fstep s a
1203+ then return res
12051204 else do
1206− res <- fstep s a
12071205 case res of
1208− Partial sres -> Done <$> fextract sres
1209− Done bres -> return $ Done bres
1206+ Partial s1 -> Done <$> fextract s1
1207+ Done b -> return $ Done b
12101208
12111209data SpanByState a bl fl fr
1212− = SpanByLeft0 !fl !fr
1213− | SpanByLeft !a !fl !fr
1210+ = SpanByLeft0 !fl
1211+ | SpanByLeft !a !fl
12141212 | SpanByRight !bl !fr
12151213
12161214-- | Break the input stream into two groups, the first group takes the input as
@@ -1231,31 +1229,50 @@ spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
12311229
12321230 where
12331231
1234− initial = SpanByLeft0 <$> initialL <*> initialR
1232+ initial = do
1233+ resL <- initialL
1234+ case resL of
1235+ Partial fl -> return $ Partial $ SpanByLeft0 fl
1236+ Done bl -> do
1237+ resR <- initialR
1238+ return
1239+ $ case resR of
1240+ Partial fr -> Partial $ SpanByRight bl fr
1241+ Done br -> Done (bl, br)
12351242
1236− step (SpanByLeft0 fl fr) input = do
1243+ step (SpanByLeft0 fl) input = do
12371244 sfl <- stepL fl input
1238− return
1239− $ Partial
1240− $ case sfl of
1241− Partial fl1 -> SpanByLeft input fl1 fr
1242− Done bl -> SpanByRight bl fr
1243− step (SpanByLeft frst fl fr) input =
1245+ case sfl of
1246+ Partial fl1 -> return $ Partial $ SpanByLeft input fl1
1247+ Done bl -> do
1248+ resR <- initialR
1249+ return
1250+ $ case resR of
1251+ Partial fr -> Partial $ SpanByRight bl fr
1252+ Done br -> Done (bl, br)
1253+ step (SpanByLeft frst fl) input =
12441254 if cmp frst input
12451255 then do
12461256 sfl <- stepL fl input
1247− return
1248− $ Partial
1249− $ case sfl of
1250− Partial fl1 -> SpanByLeft frst fl1 fr
1251− Done bl -> SpanByRight bl fr
1257+ case sfl of
1258+ Partial fl1 -> return $ Partial $ SpanByLeft frst fl1
1259+ Done bl -> do
1260+ resR <- initialR
1261+ return
1262+ $ case resR of
1263+ Partial fr -> Partial $ SpanByRight bl fr
1264+ Done br -> Done (bl, br)
12521265 else do
12531266 bl <- extractL fl
1254− sfr <- stepR fr input
1255− return
1256− $ case sfr of
1257− Partial fr1 -> Partial $ SpanByRight bl fr1
1258− Done br -> Done (bl, br)
1267+ resR <- initialR
1268+ case resR of
1269+ Partial fr -> do
1270+ sfr <- stepR fr input
1271+ return
1272+ $ case sfr of
1273+ Partial fr1 -> Partial $ SpanByRight bl fr1
1274+ Done br -> Done (bl, br)
1275+ Done br -> return $ Done (bl, br)
12591276 step (SpanByRight bl fr) input = do
12601277 sfr <- stepR fr input
12611278 return
@@ -1263,12 +1280,22 @@ spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
12631280 Partial fr1 -> Partial $ SpanByRight bl fr1
12641281 Done br -> Done (bl, br)
12651282
1266− extract (SpanByLeft0 fl fr) = (,) <$> extractL fl <*> extractR fr
1267− extract (SpanByLeft _ fl fr) = (,) <$> extractL fl <*> extractR fr
1283+ extract (SpanByLeft0 fl) = do
1284+ bl <- extractL fl
1285+ resR <- initialR
1286+ case resR of
1287+ Partial fr -> (bl, ) <$> extractR fr
1288+ Done br -> return (bl, br)
1289+ extract (SpanByLeft _ fl) = do
1290+ bl <- extractL fl
1291+ resR <- initialR
1292+ case resR of
1293+ Partial fr -> (bl, ) <$> extractR fr
1294+ Done br -> return (bl, br)
12681295 extract (SpanByRight bl fr) = (bl, ) <$> extractR fr
12691296
12701297data SpanState bl fl fr
1271− = SpanLeft !fl !fr
1298+ = SpanLeft !fl
12721299 | SpanRight !bl !fr
12731300
12741301-- | @span p f1 f2@ composes folds @f1@ and @f2@ such that @f1@ consumes the
@@ -1302,24 +1329,40 @@ span p (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
13021329
13031330 where
13041331
1305− initial = SpanLeft <$> initialL <*> initialR
1332+ initial = do
1333+ resL <- initialL
1334+ case resL of
1335+ Partial fl -> return $ Partial $ SpanLeft fl
1336+ Done bl -> do
1337+ resR <- initialR
1338+ return
1339+ $ case resR of
1340+ Partial fr -> Partial $ SpanRight bl fr
1341+ Done br -> Done (bl, br)
13061342
1307− step (SpanLeft fl fr) input =
1343+ step (SpanLeft fl) input =
13081344 if p input
13091345 then do
13101346 sfl <- stepL fl input
1311− return
1312− $ Partial
1313− $ case sfl of
1314− Partial fl1 -> SpanLeft fl1 fr
1315− Done bl -> SpanRight bl fr
1347+ case sfl of
1348+ Partial fl1 -> return $ Partial $ SpanLeft fl1
1349+ Done bl -> do
1350+ resR <- initialR
1351+ return
1352+ $ case resR of
1353+ Partial fr -> Partial $ SpanRight bl fr
1354+ Done br -> Done (bl, br)
13161355 else do
13171356 bl <- extractL fl
1318− sfr <- stepR fr input
1319− return
1320− $ case sfr of
1321− Partial fr1 -> Partial $ SpanRight bl fr1
1322− Done br -> Done (bl, br)
1357+ resR <- initialR
1358+ case resR of
1359+ Partial fr -> do
1360+ sfr <- stepR fr input
1361+ return
1362+ $ case sfr of
1363+ Partial fr1 -> Partial $ SpanRight bl fr1
1364+ Done br -> Done (bl, br)
1365+ Done br -> return $ Done (bl, br)
13231366 step (SpanRight bl fr) input = do
13241367 sfr <- stepR fr input
13251368 return
@@ -1327,7 +1370,12 @@ span p (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
13271370 Partial fr1 -> Partial $ SpanRight bl fr1
13281371 Done br -> Done (bl, br)
13291372
1330− extract (SpanLeft fl fr) = (,) <$> extractL fl <*> extractR fr
1373+ extract (SpanLeft fl) = do
1374+ bl <- extractL fl
1375+ resR <- initialR
1376+ case resR of
1377+ Partial fr -> (bl, ) <$> extractR fr
1378+ Done br -> return (bl, br)
13311379 extract (SpanRight bl fr) = (bl, ) <$> extractR fr
13321380
13331381-- |
@@ -1376,31 +1424,50 @@ spanByRolling cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR)
13761424
13771425 where
13781426
1379− initial = SpanByLeft0 <$> initialL <*> initialR
1427+ initial = do
1428+ resL <- initialL
1429+ case resL of
1430+ Partial fl -> return $ Partial $ SpanByLeft0 fl
1431+ Done bl -> do
1432+ resR <- initialR
1433+ return
1434+ $ case resR of
1435+ Partial fr -> Partial $ SpanByRight bl fr
1436+ Done br -> Done (bl, br)
13801437
1381− step (SpanByLeft0 fl fr) input = do
1438+ step (SpanByLeft0 fl) input = do
13821439 sfl <- stepL fl input
1383− return
1384− $ Partial
1385− $ case sfl of
1386− Partial fl1 -> SpanByLeft input fl1 fr
1387− Done bl -> SpanByRight bl fr
1388− step (SpanByLeft frst fl fr) input =
1389− if cmp frst input
1440+ case sfl of
1441+ Partial fl1 -> return $ Partial $ SpanByLeft input fl1
1442+ Done bl -> do
1443+ resR <- initialR
1444+ return
1445+ $ case resR of
1446+ Partial fr -> Partial $ SpanByRight bl fr
1447+ Done br -> Done (bl, br)
1448+ step (SpanByLeft input0 fl) input =
1449+ if cmp input0 input
13901450 then do
13911451 sfl <- stepL fl input
1392− return
1393− $ Partial
1394− $ case sfl of
1395− Partial fl1 -> SpanByLeft input fl1 fr
1396− Done bl -> SpanByRight bl fr
1452+ case sfl of
1453+ Partial fl1 -> return $ Partial $ SpanByLeft input fl1
1454+ Done bl -> do
1455+ resR <- initialR
1456+ return
1457+ $ case resR of
1458+ Partial fr -> Partial $ SpanByRight bl fr
1459+ Done br -> Done (bl, br)
13971460 else do
13981461 bl <- extractL fl
1399− sfr <- stepR fr input
1400− return
1401− $ case sfr of
1402− Partial fr1 -> Partial $ SpanByRight bl fr1
1403− Done br -> Done (bl, br)
1462+ resR <- initialR
1463+ case resR of
1464+ Partial fr -> do
1465+ sfr <- stepR fr input
1466+ return
1467+ $ case sfr of
1468+ Partial fr1 -> Partial $ SpanByRight bl fr1
1469+ Done br -> Done (bl, br)
1470+ Done br -> return $ Done (bl, br)
14041471 step (SpanByRight bl fr) input = do
14051472 sfr <- stepR fr input
14061473 return
@@ -1408,8 +1475,18 @@ spanByRolling cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR)
14081475 Partial fr1 -> Partial $ SpanByRight bl fr1
14091476 Done br -> Done (bl, br)
14101477
1411− extract (SpanByLeft0 fl fr) = (,) <$> extractL fl <*> extractR fr
1412− extract (SpanByLeft _ fl fr) = (,) <$> extractL fl <*> extractR fr
1478+ extract (SpanByLeft0 fl) = do
1479+ bl <- extractL fl
1480+ resR <- initialR
1481+ case resR of
1482+ Partial fr -> (bl, ) <$> extractR fr
1483+ Done br -> return (bl, br)
1484+ extract (SpanByLeft _ fl) = do
1485+ bl <- extractL fl
1486+ resR <- initialR
1487+ case resR of
1488+ Partial fr -> (bl, ) <$> extractR fr
1489+ Done br -> return (bl, br)
14131490 extract (SpanByRight bl fr) = (bl, ) <$> extractR fr
14141491
14151492------------------------------------------------------------------------------
@@ -1451,17 +1528,6 @@ breakOn pat f m = undefined
14511528tee :: Monad m => Fold m a b -> Fold m a c -> Fold m a (b,c)
14521529tee = teeWith (,)
14531530
1454−{-# INLINE foldNil #-}
1455−foldNil :: Monad m => Fold m a [b]
1456−foldNil = Fold step begin done where
1457− begin = return []
1458− step _ _ = return $ Partial []
1459− done = return
1460−
1461−{-# INLINE foldCons #-}
1462−foldCons :: Monad m => Fold m a b -> Fold m a [b] -> Fold m a [b]
1463−foldCons = teeWith (:)
1464−
14651531-- XXX use "List" instead of "[]"?, use Array for output to scale it to a large
14661532-- number of consumers? For polymorphic case a vector could be helpful. For
14671533-- Storables we can use arrays. Will need separate APIs for those.
@@ -1488,7 +1554,7 @@ foldCons = teeWith (:)
14881554-- @since 0.7.0
14891555{-# INLINE distribute #-}
14901556distribute :: Monad m => [Fold m a b] -> Fold m a [b]
1491−distribute = foldr foldCons foldNil
1557+distribute = foldr (teeWith (:)) (yield [])
14921558
14931559------------------------------------------------------------------------------
14941560-- Partitioning
@@ -1549,7 +1615,20 @@ partitionByM f (Fold stepL beginL doneL) (Fold stepR beginR doneR) =
15491615
15501616 where
15511617
1552− begin = RunBoth <$> beginL <*> beginR
1618+ begin = do
1619+ resL <- beginL
1620+ resR <- beginR
1621+ return
1622+ $ case resL of
1623+ Partial sL ->
1624+ Partial
1625+ $ case resR of
1626+ Partial sR -> RunBoth sL sR
1627+ Done bR -> RunLeft sL bR
1628+ Done bL ->
1629+ case resR of
1630+ Partial sR -> Partial $ RunRight bL sR
1631+ Done bR -> Done (bL, bR)
15531632
15541633 step (RunBoth sL sR) a = do
15551634 r <- f a
@@ -1707,10 +1786,10 @@ demux :: (Monad m, Ord k)
17071786 => Map k (Fold m a b) -> Fold m (k, a) (Map k b)
17081787demux = demuxWith id
17091788
1710−data DemuxState s b rMap kvMap =
1711− DemuxMapWithDefault !s !rMap !kvMap
1712− | DemuxMap b !rMap !kvMap
1713− | DemuxDefault s !rMap
1789+data DemuxState s b doneMap runMap =
1790+ DemuxMapAndDefault !s !doneMap !runMap
1791+ | DemuxOnlyMap b !doneMap !runMap
1792+ | DemuxOnlyDefault s !doneMap
17141793
17151794-- | Like 'demuxWith' but uses a default catchall fold to handle inputs which
17161795-- do not have a specific fold in the map to handle them.
@@ -1734,87 +1813,102 @@ demuxDefaultWith f kv (Fold dstep dinitial dextract) =
17341813
17351814 where
17361815
1737− initial =
1738− DemuxMapWithDefault
1739− <$> dinitial
1740− <*> return Map.empty
1741− <*> Prelude.mapM initialize kv
1816+ initial = do
1817+ let runInit (Fold step1 initial1 done1) = do
1818+ r <- initial1
1819+ return
1820+ $ case r of
1821+ Partial _ -> Right' (Fold step1 (return r) done1)
1822+ Done b -> Left' b
17421823
1743− step (DemuxMapWithDefault dacc results kvMap) a =
1744− if Map.size kvMap > 0
1745− then do
1746− let (k, a1) = f a
1747− case Map.lookup k kvMap of
1748− Nothing -> do
1749− res <- dstep dacc (k, a1)
1750− return
1751− $ Partial
1752− $ case res of
1753− Partial s -> DemuxMapWithDefault s results kvMap
1754− Done b -> DemuxMap b results kvMap
1755− Just (Fold step1 initial1 extract1) -> do
1756− !st <- initial1
1757− !res <- step1 st a1
1758− return
1759− $ case res of
1760− Partial s ->
1761− let fld = Fold step1 (return s) extract1
1762− kvMap1 = Map.insert k fld kvMap
1763− in Partial
1764− $ DemuxMapWithDefault
1765− dacc results kvMap1
1766− Done b ->
1767− let kvMap1 = Map.delete k kvMap
1768− results1 = Map.insert k b results
1769− in Partial
1770− $ if Map.size kvMap1 == 0
1771− then DemuxDefault dacc results1
1772− else DemuxMapWithDefault
1773− dacc results1 kvMap1
1774− -- XXX Remove this when we have Step in the initial value
1775− else error "demuxDefaultWith: empty key-value Map"
1776− step (DemuxMap dval results kvMap) a =
1777− if Map.size kvMap > 0
1778− then do
1779− let (k, a1) = f a
1780− case Map.lookup k kvMap of
1781− Nothing -> return $ Partial $ DemuxMap dval results kvMap
1782− Just (Fold step1 initial1 extract1) -> do
1783− !st <- initial1
1784− !res <- step1 st a1
1785− return
1786− $ case res of
1787− Partial s ->
1788− let fld = Fold step1 (return s) extract1
1789− kvMap1 = Map.insert k fld kvMap
1790− in Partial $ DemuxMap dval results kvMap1
1791− Done b ->
1792− let kvMap1 = Map.delete k kvMap
1793− results1 = Map.insert k b results
1794− in if Map.size kvMap1 == 0
1795− then Done (results1, dval)
1796− else Partial
1797− $ DemuxMap dval results1 kvMap1
1798− -- XXX Remove this when we have Step in the initial value
1799− else error "demuxDefaultWith: empty key-value Map"
1800− step (DemuxDefault dacc results) a = do
1824+ -- initialize folds in the kv map and separate the ones that are done
1825+ -- from running ones
1826+ kv1 <- Prelude.mapM runInit kv
1827+ let runMap = Map.map fromRight' $ Map.filter isRight' kv1
1828+ doneMap = Map.map fromLeft' $ Map.filter isLeft' kv1
1829+
1830+ -- Run the default fold, and decide the next state based on its result
1831+ dres <- dinitial
1832+ return
1833+ $ case dres of
1834+ Partial s ->
1835+ Partial
1836+ $ if Map.size runMap > 0
1837+ then DemuxMapAndDefault s doneMap runMap
1838+ else DemuxOnlyDefault s doneMap
1839+ Done b ->
1840+ if Map.size runMap > 0
1841+ then Partial $ DemuxOnlyMap b doneMap runMap
1842+ else Done (doneMap, b)
1843+
1844+ {-# INLINE runFold #-}
1845+ runFold fPartial fDone doneMap runMap (Fold step1 initial1 done1) k a1 = do
1846+ resi <- initial1
1847+ case resi of
1848+ Partial st -> do
1849+ res <- step1 st a1
1850+ return $ case res of
1851+ Partial s ->
1852+ let fld = Fold step1 (return $ Partial s) done1
1853+ runMap1 = Map.insert k fld runMap
1854+ in Partial $ fPartial doneMap runMap1
1855+ Done b -> do
1856+ let runMap1 = Map.delete k runMap
1857+ doneMap1 = Map.insert k b doneMap
1858+ if Map.size runMap1 == 0
1859+ then fDone doneMap1
1860+ else Partial $ fPartial doneMap1 runMap1
1861+ Done _ -> error "Bug: demuxDefaultWith: Done fold"
1862+
1863+ step (DemuxMapAndDefault dacc doneMap runMap) a = do
1864+ let (k, a1) = f a
1865+ case Map.lookup k runMap of
1866+ Nothing -> do
1867+ res <- dstep dacc (k, a1)
1868+ return
1869+ $ Partial
1870+ $ case res of
1871+ Partial s -> DemuxMapAndDefault s doneMap runMap
1872+ Done b -> DemuxOnlyMap b doneMap runMap
1873+ Just fld ->
1874+ runFold
1875+ (DemuxMapAndDefault dacc)
1876+ (Partial . DemuxOnlyDefault dacc)
1877+ doneMap runMap fld k a1
1878+
1879+ step (DemuxOnlyMap dval doneMap runMap) a = do
1880+ let (k, a1) = f a
1881+ case Map.lookup k runMap of
1882+ Nothing -> return $ Partial $ DemuxOnlyMap dval doneMap runMap
1883+ Just fld ->
1884+ runFold
1885+ (DemuxOnlyMap dval)
1886+ (Done . (, dval))
1887+ doneMap runMap fld k a1
1888+ step (DemuxOnlyDefault dacc doneMap) a = do
18011889 let (k, a1) = f a
18021890 res <- dstep dacc (k, a1)
18031891 return
18041892 $ case res of
1805− Partial s -> Partial $ DemuxDefault s results
1806− Done b -> Done (results, b)
1893+ Partial s -> Partial $ DemuxOnlyDefault s doneMap
1894+ Done b -> Done (doneMap, b)
18071895
1808− extract (DemuxMapWithDefault dacc results kvMap) = do
1896+ runExtract (Fold _ initial1 done1) = do
1897+ res <- initial1
1898+ case res of
1899+ Partial s -> done1 s
1900+ Done b -> return b
1901+
1902+ extract (DemuxMapAndDefault dacc doneMap runMap) = do
18091903 b <- dextract dacc
1810− kvMap1 <- Prelude.mapM (\(Fold _ i d) -> i >>= d) kvMap
1811− return (results `Map.union` kvMap1, b)
1812− extract (DemuxMap dval results kvMap) = do
1813− kvMap1 <- Prelude.mapM (\(Fold _ i d) -> i >>= d) kvMap
1814− return (results `Map.union` kvMap1, dval)
1815− extract (DemuxDefault dacc results) = do
1904+ runMap1 <- Prelude.mapM runExtract runMap
1905+ return (doneMap `Map.union` runMap1, b)
1906+ extract (DemuxOnlyMap dval doneMap runMap) = do
1907+ runMap1 <- Prelude.mapM runExtract runMap
1908+ return (doneMap `Map.union` runMap1, dval)
1909+ extract (DemuxOnlyDefault dacc doneMap) = do
18161910 b <- dextract dacc
1817− return (results, b)
1911+ return (doneMap, b)
18181912
18191913{-# INLINE demuxDefault #-}
18201914demuxDefault :: (Monad m, Ord k)
@@ -1844,43 +1938,44 @@ demuxDefault = demuxDefaultWith id
18441938--
18451939{-# INLINE classifyWith #-}
18461940classifyWith :: (Monad m, Ord k) => (a -> k) -> Fold m a b -> Fold m a (Map k b)
1847−classifyWith f (Fold step initial extract) = Fold step' initial' extract'
1941+classifyWith f (Fold step1 initial1 extract1) = mkAccumM step initial extract
18481942
18491943 where
18501944
1851− initial' = return Map.empty
1945+ initial = return Map.empty
18521946
1853− step' kv a =
1947+ step kv a =
18541948 case Map.lookup k kv of
18551949 Nothing -> do
1856− x <- initial
1857− r <- step x a
1858− return
1859− $ Partial
1860− $ flip (Map.insert k) kv
1861− $ case r of
1862− Partial sr -> Left' sr
1863− Done br -> Right' br
1950+ x <- initial1
1951+ case x of
1952+ Partial s -> do
1953+ r <- step1 s a
1954+ return
1955+ $ flip (Map.insert k) kv
1956+ $ case r of
1957+ Partial s1 -> Left' s1
1958+ Done b -> Right' b
1959+ Done b -> return $ Map.insert k (Right' b) kv
18641960 Just x -> do
18651961 case x of
18661962 Left' s -> do
1867− r <- step s a
1963+ r <- step1 s a
18681964 return
1869− $ Partial
18701965 $ flip (Map.insert k) kv
18711966 $ case r of
1872− Partial sr -> Left' sr
1873− Done br -> Right' br
1874− Right' _ -> return $ Partial kv
1967+ Partial s1 -> Left' s1
1968+ Done b -> Right' b
1969+ Right' _ -> return kv
18751970
18761971 where
18771972
18781973 k = f a
18791974
1880− extract' =
1975+ extract =
18811976 Prelude.mapM
18821977 (\case
1883− Left' s -> extract s
1978+ Left' s -> extract1 s
18841979 Right' b -> return b)
18851980
18861981-- | Given an input stream of key value pairs and a fold for values, fold all
@@ -1920,7 +2015,20 @@ unzipWithM f (Fold stepL beginL doneL) (Fold stepR beginR doneR) =
19202015
19212016 where
19222017
1923− begin = RunBoth <$> beginL <*> beginR
2018+ begin = do
2019+ resL <- beginL
2020+ resR <- beginR
2021+ return
2022+ $ case resL of
2023+ Partial sL ->
2024+ Partial
2025+ $ case resR of
2026+ Partial sR -> RunBoth sL sR
2027+ Done bR -> RunLeft sL bR
2028+ Done bL ->
2029+ case resR of
2030+ Partial sR -> Partial $ RunRight bL sR
2031+ Done bR -> Done (bL, bR)
19242032
19252033 step (RunBoth sL sR) a = do
19262034 (b, c) <- f a
@@ -2048,7 +2156,7 @@ toParallelSVar svar winfo = Fold step initial extract
20482156
20492157 where
20502158
2051− initial = return ()
2159+ initial = return $ Partial ()
20522160
20532161 -- XXX we can have a separate fold for unlimited buffer case to avoid a
20542162 -- branch in the step here.
@@ -2067,7 +2175,7 @@ toParallelSVarLimited svar winfo = Fold step initial extract
20672175
20682176 where
20692177
2070− initial = return True
2178+ initial = return $ Partial True
20712179
20722180 step True x =
20732181 liftIO $ do