Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions core/src/Streamly/Internal/Data/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -2153,11 +2151,11 @@ groupByRollingEither
-- Right "string"
--
-- >>> Stream.parsePos (Parser.listEqBy (==) "mismatch") $ Stream.fromList "match"
-- Left (ParseErrorPos 2 "streamEqBy: mismtach occurred")
-- Left (ParseErrorPos 2 "listEqBy: mismatch after matching 1 elements")
--
{-# 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

Expand Down Expand Up @@ -2188,41 +2186,45 @@ 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

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 "streamEqBy: mismtach 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 "streamEqBy: 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 "streamEqBy: 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.
Expand All @@ -2231,7 +2233,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
Expand Down
Loading