on master help sign in
Implementation of groupByRollingEither
commit9e29c70b60928ea5e1c3c54d5fe5c15e2338025e authorRanjeet Kumar Ranjan <ranjeetr@composewell.com> dateTue 5 Oct 2021, 16:04 (5 years ago) parente4e8797
2 files changed+91−2
src/Streamly/Internal/Data/Parser.hs+2−2 src/Streamly/Internal/Data/Parser/ParserD.hs+89
src/Streamly/Internal/Data/Parser.hs+2−2
@@ -721,9 +721,9 @@ groupByRolling eq = K.toParserK . D.groupByRolling eq
721721--
722722-- /Unimplemented/
723723{-# INLINABLE groupByRollingEither #-}
724−groupByRollingEither :: -- MonadCatch m =>
724+groupByRollingEither :: MonadCatch m =>
725725 (a -> a -> Bool) -> Fold m a b -> Fold m a b -> Parser m a (Either b b)
726−groupByRollingEither = undefined
726+groupByRollingEither eq f1 = K.toParserK . D.groupByRollingEither eq f1
727727
728728-- | Match the given sequence of elements using the given comparison function.
729729--
src/Streamly/Internal/Data/Parser/ParserD.hs+89
@@ -71,6 +71,7 @@ module Streamly.Internal.Data.Parser.ParserD
7171 , wordBy
7272 , groupBy
7373 , groupByRolling
74+ , groupByRollingEither
7475 , eqBy
7576 -- , prefixOf -- match any prefix of a given string
7677 -- , suffixOf -- match any suffix of a given string
@@ -733,6 +734,13 @@ data GroupByState a s
733734 = GroupByInit !s
734735 | GroupByGrouping !a !s
735736
737+{-# ANN type GroupByStatePair Fuse #-}
738+data GroupByStatePair a s1 s2
739+ = GroupByInitPair !s1 !s2
740+ | GroupByGroupingPair !a !s1 !s2
741+ | GroupByGroupingPairL !a !s1 !s2
742+ | GroupByGroupingPairR !a !s1 !s2
743+
736744-- | See 'Streamly.Internal.Data.Parser.groupBy'.
737745--
738746{-# INLINE groupBy #-}
@@ -797,6 +805,87 @@ groupByRolling eq (Fold fstep finitial fextract) = Parser step initial extract
797805 extract (GroupByInit s) = fextract s
798806 extract (GroupByGrouping _ s) = fextract s
799807
808+{-# INLINABLE groupByRollingEither #-}
809+groupByRollingEither :: MonadCatch m =>
810+ (a -> a -> Bool) -> Fold m a b -> Fold m a b -> Parser m a (Either b b)
811+groupByRollingEither
812+ eq
813+ (Fold fstep1 finitial1 fextract1)
814+ (Fold fstep2 finitial2 fextract2) = Parser step initial extract
815+
816+ where
817+
818+ {-# INLINE grouper #-}
819+ grouper s1 s2 a = do
820+ return $ Continue 0 (GroupByGroupingPair a s1 s2)
821+
822+ {-# INLINE grouperL2 #-}
823+ grouperL2 s1 s2 a = do
824+ res <- fstep1 s1 a
825+ return
826+ $ case res of
827+ FL.Done b -> Done 0 (Left b)
828+ FL.Partial s11 -> Partial 0 (GroupByGroupingPairL a s11 s2)
829+
830+ {-# INLINE grouperL #-}
831+ grouperL s1 s2 a0 a = do
832+ res <- fstep1 s1 a0
833+ case res of
834+ FL.Done b -> return $ Done 0 (Left b)
835+ FL.Partial s11 -> grouperL2 s11 s2 a
836+
837+ {-# INLINE grouperR2 #-}
838+ grouperR2 s1 s2 a = do
839+ res <- fstep2 s2 a
840+ return
841+ $ case res of
842+ FL.Done b -> Done 0 (Right b)
843+ FL.Partial s21 -> Partial 0 (GroupByGroupingPairR a s1 s21)
844+
845+ {-# INLINE grouperR #-}
846+ grouperR s1 s2 a0 a = do
847+ res <- fstep2 s2 a0
848+ case res of
849+ FL.Done b -> return $ Done 0 (Right b)
850+ FL.Partial s21 -> grouperR2 s1 s21 a
851+
852+ initial = do
853+ res1 <- finitial1
854+ res2 <- finitial2
855+ return
856+ $ case res1 of
857+ FL.Partial s1 ->
858+ case res2 of
859+ FL.Partial s2 -> IPartial $ GroupByInitPair s1 s2
860+ FL.Done b -> IDone (Left b)
861+ FL.Done b -> IDone (Left b)
862+
863+ step (GroupByInitPair s1 s2) a = grouper s1 s2 a
864+
865+ step (GroupByGroupingPair a0 s1 s2) a =
866+ if not (eq a0 a)
867+ then grouperL s1 s2 a0 a
868+ else grouperR s1 s2 a0 a
869+
870+ step (GroupByGroupingPairL a0 s1 s2) a =
871+ if not (eq a0 a)
872+ then grouperL2 s1 s2 a
873+ else Done 1 . Left <$> fextract1 s1
874+
875+ step (GroupByGroupingPairR a0 s1 s2) a =
876+ if eq a0 a
877+ then grouperR2 s1 s2 a
878+ else Done 1 . Right <$> fextract2 s2
879+
880+ extract (GroupByInitPair s1 _) = Left <$> fextract1 s1
881+ extract (GroupByGroupingPairL _ s1 _) = Left <$> fextract1 s1
882+ extract (GroupByGroupingPairR _ _ s2) = Right <$> fextract2 s2
883+ extract (GroupByGroupingPair a s1 _) = do
884+ res <- fstep1 s1 a
885+ case res of
886+ FL.Done b -> return $ Left b
887+ FL.Partial s11 -> Left <$> fextract1 s11
888+
800889-- XXX use an Unfold instead of a list?
801890-- XXX custom combinators for matching list, array and stream?
802891--