on master help sign in
Add sepByAll
e7feb6cHarendra Kumar
core/src/Streamly/Internal/Data/Parser/ParserD.hs+19−2
@@ -200,6 +200,7 @@ module Streamly.Internal.Data.Parser.ParserD
200 -- @
200 -- @
201 , sepBy1
201 , sepBy1
202 , sepBy
202 , sepBy
203+ , sepByAll
203
204
204 -- ** Sequential Alternative
205 -- ** Sequential Alternative
205 , alt
206 , alt
@@ -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.
2539+--
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
2542+-- parse it.
2538
2543
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.
2541--
2546--
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:
2973--
2978--
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)
2976--
2981--
2977-- Examples:
2982-- Examples:
2978--
2983--
@@ -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)
2994sepBy
3001sepBy
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
3085
3092
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)
3098+
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.
3088
3101
@@ -3106,6 +3119,10 @@ sepBy1 p sep sink = do
3106
3119
3107-- | Like 'sepBy' but requires at least one successful parse.
3120-- | Like 'sepBy' but requires at least one successful parse.
3108--
3121--
3122+-- Definition:
3123+--
3124+-- >>> sepBy1 p1 p2 f = Parser.deintercalate1 p1 p2 (Fold.catLefts f)
3125+--
3109-- Examples:
3126-- Examples:
3110--
3127--
3111-- >>> p1 = Parser.takeWhile1 (not . (== '+')) Fold.toList
3128-- >>> p1 = Parser.takeWhile1 (not . (== '+')) Fold.toList