@@ -200,6 +200,7 @@ module Streamly.Internal.Data.Parser.ParserD
204 -- ** Sequential Alternative
205 -- ** Sequential Alternative
@@ -2535,9 +2536,13 @@ data DeintercalateAllState fs sp ss =
2535-- useful. For example, in case of JSON parsing we get an entire block of
2536-- useful. For example, in case of JSON parsing we get an entire block of
2536-- key-value pairs which we need to verify. This version may be simpler, more
2537-- key-value pairs which we need to verify. This version may be simpler, more
2537-- efficient. We could implement this as a stream operation like parseMany.
2538-- efficient. We could implement this as a stream operation like parseMany.
2540+-- XXX Also, it may be a good idea to provide a parse driver for a fold. For
2541+-- example, in case of csv parsing as we are feeding a line to a fold we can
2539-- | Like 'deintercalate' but the entire input must satisfy the pattern
2544-- | Like 'deintercalate' but the entire input must satisfy the pattern
2540−-- otherwise the parser fails.
2545+-- otherwise the parser fails. This is many times faster than deintercalate.
2542-- >>> p1 = Parser.takeWhile1 (not . (== '+')) Fold.toList
2547-- >>> p1 = Parser.takeWhile1 (not . (== '+')) Fold.toList
2543-- >>> p2 = Parser.satisfy (== '+')
2548-- >>> p2 = Parser.satisfy (== '+')
@@ -2972,7 +2977,7 @@ data SepByState fs sp ss =
2972-- Definitions:
2977-- Definitions:
2974-- >>> sepBy p1 p2 f = Parser.deintercalate p1 p2 (Fold.catLefts f)
2979-- >>> sepBy p1 p2 f = Parser.deintercalate p1 p2 (Fold.catLefts f)
2975−-- >>> sepBy p1 p2 f = Parser.sepBy1 p1 p2 f <|> return mempty
2980+-- >>> sepBy p1 p2 f = Parser.sepBy1 p1 p2 f <|> Parser.fromEffect (Fold.extractM f)
2977-- Examples:
2982-- Examples:
@@ -2991,6 +2996,8 @@ data SepByState fs sp ss =
2991{-# INLINE sepBy #-}
2996{-# INLINE sepBy #-}
2992sepBy :: Monad m =>
2997sepBy :: Monad m =>
2993 Parser a m b -> Parser a m x -> Fold m b c -> Parser a m c
2998 Parser a m b -> Parser a m x -> Fold m b c -> Parser a m c
2999+-- This has similar performance as the custom impl below.
3000+-- sepBy p1 p2 f = deintercalate p1 p2 (FL.catLefts f)
2995 (Parser stepL initialL extractL)
3002 (Parser stepL initialL extractL)
2996 (Parser stepR initialR _)
3003 (Parser stepR initialR _)
@@ -3083,6 +3090,12 @@ sepBy
3083 extract (SepByInitR fs) = fmap (Done 0) $ fextract fs
3090 extract (SepByInitR fs) = fmap (Done 0) $ fextract fs
3084 extract (SepByR cnt fs _) = fmap (Done cnt) $ fextract fs
3091 extract (SepByR cnt fs _) = fmap (Done cnt) $ fextract fs
3093+-- | Non-backtracking version of sepBy. Several times faster.
3094+{-# INLINE sepByAll #-}
3095+sepByAll :: Monad m =>
3096+ Parser a m b -> Parser a m x -> Fold m b c -> Parser a m c
3097+sepByAll p1 p2 f = deintercalateAll p1 p2 (FL.catLefts f)
3086-- XXX This can be implemented using refold, parse one and then continue
3099-- XXX This can be implemented using refold, parse one and then continue
3087-- collecting the rest in that.
3100-- collecting the rest in that.
@@ -3106,6 +3119,10 @@ sepBy1 p sep sink = do
3107-- | Like 'sepBy' but requires at least one successful parse.
3120-- | Like 'sepBy' but requires at least one successful parse.
3124+-- >>> sepBy1 p1 p2 f = Parser.deintercalate1 p1 p2 (Fold.catLefts f)
3109-- Examples:
3126-- Examples:
3111-- >>> p1 = Parser.takeWhile1 (not . (== '+')) Fold.toList
3128-- >>> p1 = Parser.takeWhile1 (not . (== '+')) Fold.toList