From 4cebfe885d64536a0e6143ee2c05057a19fcce4b Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Mon, 22 Jun 2026 08:54:19 +0530 Subject: [PATCH 1/2] Mention correct function name in parser error --- core/src/Streamly/Internal/Data/Parser.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/Streamly/Internal/Data/Parser.hs b/core/src/Streamly/Internal/Data/Parser.hs index e86c56fbb0..76fd6e5182 100644 --- a/core/src/Streamly/Internal/Data/Parser.hs +++ b/core/src/Streamly/Internal/Data/Parser.hs @@ -2153,11 +2153,11 @@ groupByRollingEither -- Right "string" -- -- >>> Stream.parsePos (Parser.listEqBy (==) "mismatch") $ Stream.fromList "match" --- Left (ParseErrorPos 2 "streamEqBy: mismtach occurred") +-- Left (ParseErrorPos 2 "listEqBy: mismatch occurred") -- {-# INLINE listEqBy #-} listEqBy :: Monad m => (a -> a -> Bool) -> [a] -> Parser a m [a] -listEqBy cmp xs = streamEqByInternal cmp (D.fromList xs) *> fromPure xs +listEqBy cmp xs = streamEqByInternal "listEqBy" cmp (D.fromList xs) *> fromPure xs {- listEqBy cmp str = Parser step initial extract @@ -2188,8 +2188,8 @@ listEqBy cmp str = Parser step initial extract -} {-# INLINE streamEqByInternal #-} -streamEqByInternal :: Monad m => (a -> a -> Bool) -> D.Stream m a -> Parser a m () -streamEqByInternal cmp (D.Stream sstep state) = Parser step initial extract +streamEqByInternal :: Monad m => String -> (a -> a -> Bool) -> D.Stream m a -> Parser a m () +streamEqByInternal fname cmp (D.Stream sstep state) = Parser step initial extract where @@ -2210,7 +2210,7 @@ streamEqByInternal cmp (D.Stream sstep state) = Parser step initial extract D.Yield x1 s -> SContinue 1 (Just' x1, s) D.Stop -> SDone 1 () D.Skip s -> SContinue 0 (Nothing', s) - else return $ SError "streamEqBy: mismtach occurred" + else return $ SError (fname ++ ": mismatch occurred") step (Nothing', st) a = do r <- sstep defState st return @@ -2218,11 +2218,11 @@ streamEqByInternal cmp (D.Stream sstep state) = Parser step initial extract D.Yield x s -> do if x `cmp` a then SContinue 1 (Nothing', s) - else SError "streamEqBy: mismatch occurred" + else SError (fname ++ ": mismatch occurred") D.Stop -> SDone 0 () D.Skip s -> SContinue 0 (Nothing', s) - extract _ = return $ FError "streamEqBy: end of input" + extract _ = return $ FError (fname ++ ": end of input") -- | Like 'listEqBy' but uses a stream instead of a list and does not return -- the stream. @@ -2231,7 +2231,7 @@ streamEqByInternal cmp (D.Stream sstep state) = Parser step initial extract streamEqBy :: Monad m => (a -> a -> Bool) -> D.Stream m a -> Parser a m () -- XXX Somehow composing this with "*>" is much faster on the microbenchmark. -- Need to investigate why. -streamEqBy cmp stream = streamEqByInternal cmp stream *> fromPure () +streamEqBy cmp stream = streamEqByInternal "streamEqBy" cmp stream *> fromPure () -- Rename to "list". -- | Match the input sequence with the supplied list and return it if From e121cb1275fd8c9afe5ae8f6cb1498f0ae95d704 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Mon, 22 Jun 2026 09:12:47 +0530 Subject: [PATCH 2/2] Add an error location counter in streamEqBy parser --- core/src/Streamly/Internal/Data/Parser.hs | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/core/src/Streamly/Internal/Data/Parser.hs b/core/src/Streamly/Internal/Data/Parser.hs index 76fd6e5182..cd2b99baf7 100644 --- a/core/src/Streamly/Internal/Data/Parser.hs +++ b/core/src/Streamly/Internal/Data/Parser.hs @@ -2136,9 +2136,7 @@ groupByRollingEither FL.Done b -> return $ FDone 0 (Left b) FL.Partial s11 -> FDone 0 . Left <$> ffinal1 s11 --- XXX use an Unfold instead of a list? --- XXX custom combinators for matching list, array and stream? --- XXX rename to listBy? +-- XXX custom combinator for matching, array as well? -- | Match the given sequence of elements using the given comparison function. -- Returns the original sequence if successful. @@ -2153,7 +2151,7 @@ groupByRollingEither -- Right "string" -- -- >>> Stream.parsePos (Parser.listEqBy (==) "mismatch") $ Stream.fromList "match" --- Left (ParseErrorPos 2 "listEqBy: mismatch occurred") +-- Left (ParseErrorPos 2 "listEqBy: mismatch after matching 1 elements") -- {-# INLINE listEqBy #-} listEqBy :: Monad m => (a -> a -> Bool) -> [a] -> Parser a m [a] @@ -2196,33 +2194,37 @@ streamEqByInternal fname cmp (D.Stream sstep state) = Parser step initial extrac initial = do r <- sstep defState state case r of - D.Yield x s -> return $ IPartial (Just' x, s) + D.Yield x s -> return $ IPartial (Just' x, s, 0 :: Int) D.Stop -> return $ IDone () -- Need Skip/Continue in initial to loop right here - D.Skip s -> return $ IPartial (Nothing', s) + D.Skip s -> return $ IPartial (Nothing', s, 0) - step (Just' x, st) a = + step (Just' x, st, n) a = if x `cmp` a then do r <- sstep defState st return $ case r of - D.Yield x1 s -> SContinue 1 (Just' x1, s) + D.Yield x1 s -> SContinue 1 (Just' x1, s, n + 1) D.Stop -> SDone 1 () - D.Skip s -> SContinue 0 (Nothing', s) - else return $ SError (fname ++ ": mismatch occurred") - step (Nothing', st) a = do + D.Skip s -> SContinue 0 (Nothing', s, n + 1) + else return $ SError + (fname ++ ": mismatch after matching " ++ show n ++ " elements") + step (Nothing', st, n) a = do r <- sstep defState st return $ case r of D.Yield x s -> do if x `cmp` a - then SContinue 1 (Nothing', s) - else SError (fname ++ ": mismatch occurred") + then SContinue 1 (Nothing', s, n + 1) + else SError + (fname ++ ": mismatch after matching " + ++ show n ++ " elements") D.Stop -> SDone 0 () - D.Skip s -> SContinue 0 (Nothing', s) + D.Skip s -> SContinue 0 (Nothing', s, n) - extract _ = return $ FError (fname ++ ": end of input") + extract (_, _, n) = return $ FError + (fname ++ ": end of input after matching " ++ show n ++ " elements") -- | Like 'listEqBy' but uses a stream instead of a list and does not return -- the stream.