on master help sign in
Implement takeWhileP parser
8bf2703Harendra Kumar
core/src/Streamly/Internal/Data/Parser.hs+14−7
@@ -578,6 +578,8 @@ takeGE n = D.toParserK . D.takeGE n
578-- $takeWhile
578-- $takeWhile
579-- Note: This is called @takeWhileP@ and @munch@ in some parser libraries.
579-- Note: This is called @takeWhileP@ and @munch@ in some parser libraries.
580
580
581+-- XXX We should perhaps use only takeWhileP and rename it to takeWhile.
582+--
581-- | Like 'takeWhile' but uses a 'Parser' instead of a 'Fold' to collect the
583-- | Like 'takeWhile' but uses a 'Parser' instead of a 'Fold' to collect the
582-- input. The combinator stops when the condition fails or if the collecting
584-- input. The combinator stops when the condition fails or if the collecting
583-- parser stops.
585-- parser stops.
@@ -585,19 +587,16 @@ takeGE n = D.toParserK . D.takeGE n
585-- This is a generalized version of takeWhile, for example 'takeWhile1' can be
587-- This is a generalized version of takeWhile, for example 'takeWhile1' can be
586-- implemented in terms of this:
588-- implemented in terms of this:
587--
589--
588−-- @
589−-- takeWhile1 cond p = takeWhile cond (takeBetween 1 maxBound p)
590+-- >>> takeWhile1 cond p = takeWhile cond (takeBetween 1 maxBound p)
590−-- @
591--
591--
592-- Stops: when the condition fails or the collecting parser stops.
592-- Stops: when the condition fails or the collecting parser stops.
593-- Fails: when the collecting parser fails.
593-- Fails: when the collecting parser fails.
594--
594--
595−-- /Unimplemented/
595+-- /Pre-release/
596--
596--
597{-# INLINE takeWhileP #-}
597{-# INLINE takeWhileP #-}
598−takeWhileP :: -- MonadCatch m =>
599− (a -> Bool) -> Parser m a b -> Parser m a b
598+takeWhileP :: MonadCatch m => (a -> Bool) -> Parser m a b -> Parser m a b
600−takeWhileP _cond = undefined -- D.toParserK . D.takeWhileP cond
599+takeWhileP cond p = D.toParserK $ D.takeWhileP cond (D.fromParserK p)
601
600
602-- | Collect stream elements until an element fails the predicate. The element
601-- | Collect stream elements until an element fails the predicate. The element
603-- on which the predicate fails is returned back to the input stream.
602-- on which the predicate fails is returned back to the input stream.
@@ -608,6 +607,8 @@ takeWhileP _cond = undefined -- D.toParserK . D.takeWhileP cond
608-- >>> Stream.parse (Parser.takeWhile (== 0) Fold.toList) $ Stream.fromList [0,0,1,0,1]
607-- >>> Stream.parse (Parser.takeWhile (== 0) Fold.toList) $ Stream.fromList [0,0,1,0,1]
609-- [0,0]
608-- [0,0]
610--
609--
610+-- >>> takeWhile cond f = Parser.takeWhileP cond (Parser.fromFold f)
611+--
611-- We can implement a @breakOn@ using 'takeWhile':
612-- We can implement a @breakOn@ using 'takeWhile':
612--
613--
613-- @
614-- @
@@ -619,20 +620,26 @@ takeWhileP _cond = undefined -- D.toParserK . D.takeWhileP cond
619{-# INLINE takeWhile #-}
620{-# INLINE takeWhile #-}
620takeWhile :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
621takeWhile :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
621takeWhile cond = D.toParserK . D.takeWhile cond
622takeWhile cond = D.toParserK . D.takeWhile cond
623+-- takeWhile cond f = takeWhileP cond (fromFold f)
622
624
623-- | Like 'takeWhile' but takes at least one element otherwise fails.
625-- | Like 'takeWhile' but takes at least one element otherwise fails.
624--
626--
627+-- >>> takeWhile1 cond p = Parser.takeWhileP cond (Parser.takeBetween 1 maxBound p)
628+--
625-- /Pre-release/
629-- /Pre-release/
626--
630--
627{-# INLINE takeWhile1 #-}
631{-# INLINE takeWhile1 #-}
628takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
632takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
629takeWhile1 cond = D.toParserK . D.takeWhile1 cond
633takeWhile1 cond = D.toParserK . D.takeWhile1 cond
634+-- takeWhile1 cond f = takeWhileP cond (takeBetween 1 maxBound f)
630
635
631-- | Drain the input as long as the predicate succeeds, running the effects and
636-- | Drain the input as long as the predicate succeeds, running the effects and
632-- discarding the results.
637-- discarding the results.
633--
638--
634-- This is also called @skipWhile@ in some parsing libraries.
639-- This is also called @skipWhile@ in some parsing libraries.
635--
640--
641+-- >>> dropWhile p = Parser.takeWhile p Fold.drain
642+--
636-- /Pre-release/
643-- /Pre-release/
637--
644--
638{-# INLINE dropWhile #-}
645{-# INLINE dropWhile #-}
core/src/Streamly/Internal/Data/Parser/ParserD.hs+17
@@ -68,6 +68,7 @@ module Streamly.Internal.Data.Parser.ParserD
68 -- Grab a sequence of input elements by inspecting them
68 -- Grab a sequence of input elements by inspecting them
69 , lookAhead
69 , lookAhead
70 , takeWhile
70 , takeWhile
71+ , takeWhileP
71 , takeWhile1
72 , takeWhile1
72
73
73 -- Separators
74 -- Separators
@@ -580,6 +581,22 @@ takeGE n (Fold fstep finitial fextract) = Parser step initial extract
580-- Conditional splitting
581-- Conditional splitting
581-------------------------------------------------------------------------------
582-------------------------------------------------------------------------------
582
583
584+-- | See 'Streamly.Internal.Data.Parser.takeWhileP'.
585+--
586+-- /Pre-release/
587+--
588+{-# INLINE takeWhileP #-}
589+takeWhileP :: Monad m => (a -> Bool) -> Parser m a b -> Parser m a b
590+takeWhileP predicate (Parser pstep pinitial pextract) =
591+ Parser step pinitial pextract
592+
593+ where
594+
595+ step s a =
596+ if predicate a
597+ then pstep s a
598+ else Done 1 <$> pextract s
599+
583-- | See 'Streamly.Internal.Data.Parser.takeWhile'.
600-- | See 'Streamly.Internal.Data.Parser.takeWhile'.
584--
601--
585-- /Pre-release/
602-- /Pre-release/