@@ -54,8 +54,6 @@ module Streamly.Internal.Data.Parser
5454 -- First order parsers
5555 -- * Accumulators
5656 , fromFold
57− , any
58− , all
5957 , yield
6058 , yieldM
6159 , die
@@ -75,8 +73,7 @@ module Streamly.Internal.Data.Parser
7573
7674 -- | Grab a sequence of input elements without inspecting them
7775 , takeBetween
78− , take -- takeBetween 0 n
79− -- $take
76+ -- , take -- takeBetween 0 n
8077 , takeEQ -- takeBetween n n
8178 , takeGE -- takeBetween n maxBound
8279
@@ -86,11 +83,9 @@ module Streamly.Internal.Data.Parser
8683 , takeWhile
8784 -- $takeWhile
8885 , takeWhile1
86+ , drainWhile
8987
90− , sliceSepByP
9188 , sliceSepBy
92− , sliceSepByMax
93− , sliceEndWith
9489 , sliceBeginWith
9590 , sliceSepWith
9691 , escapedSliceSepBy
@@ -134,7 +129,7 @@ module Streamly.Internal.Data.Parser
134129
135130 -- * N-ary Combinators
136131 -- ** Sequential Collection
137− , sequence
132+ , concatSequence
138133 , concatMap
139134
140135 -- ** Sequential Repetition
@@ -206,6 +201,7 @@ import Prelude
206201import Streamly.Internal.Data.Fold.Types (Fold(..))
207202import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
208203
204+import qualified Streamly.Internal.Data.Fold as FL
209205import qualified Streamly.Internal.Data.Parser.ParserD as D
210206import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
211207
@@ -225,22 +221,6 @@ fromFold = K.toParserK . D.fromFold
225221-- Terminating but not failing folds
226222-------------------------------------------------------------------------------
227223--
228−-- |
229−-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
230−-- > True
231−--
232−{-# INLINE any #-}
233−any :: MonadCatch m => (a -> Bool) -> Parser m a Bool
234−any = K.toParserK . D.any
235−
236−-- |
237−-- >>> S.parse (PR.all (== 0)) $ S.fromList [1,0,1]
238−-- > False
239−--
240−{-# INLINE all #-}
241−all :: MonadCatch m => (a -> Bool) -> Parser m a Bool
242−all = K.toParserK . D.all
243−
244224-- This is the dual of stream "yield".
245225--
246226-- | A parser that always yields a pure value without consuming any input.
@@ -377,35 +357,6 @@ takeBetween :: -- MonadCatch m =>
377357 Int -> Int -> Fold m a b -> Parser m a b
378358takeBetween _m _n = undefined -- K.toParserK . D.takeBetween m n
379359
380−--
381−-- $take
382−-- Note: this is called takeP in some parser libraries.
383−--
384−-- TODO Once we have terminating folds, this Parse should get replaced by Fold.
385−-- Alternatively, we can name it "chunkOf" and the corresponding time domain
386−-- combinator as "intervalOf" or even "chunk" and "interval".
387−
388−-- | Take at most @n@ input elements and fold them using the supplied fold.
389−--
390−-- Stops after @n@ elements.
391−-- Never fails.
392−--
393−-- >>> S.parse (PR.take 1 FL.toList) $ S.fromList [1]
394−-- [1]
395−--
396−-- >>> S.parse (PR.take (-1) FL.toList) $ S.fromList [1]
397−-- []
398−--
399−-- @
400−-- S.chunksOf n f = S.parseMany (FL.take n f)
401−-- @
402−--
403−-- /Internal/
404−--
405−{-# INLINE take #-}
406−take :: MonadCatch m => Int -> Fold m a b -> Parser m a b
407−take n = K.toParserK . D.take n
408−
409360-- | Stops after taking exactly @n@ input elements.
410361--
411362-- * Stops - after consuming @n@ elements.
@@ -423,8 +374,9 @@ takeEQ n = K.toParserK . D.takeEQ n
423374
424375-- | Take at least @n@ input elements, but can collect more.
425376--
426−-- * Stops - never.
427−-- * Fails - if the stream end before producing @n@ elements.
377+-- * Stops - when the collecting fold stops.
378+-- * Fails - if the stream or the collecting fold ends before producing @n@
379+-- elements.
428380--
429381-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
430382-- > "takeGE: Expecting at least 4 elements, got only 3"
@@ -465,7 +417,7 @@ takeWhileP _cond = undefined -- K.toParserK . D.takeWhileP cond
465417-- | Collect stream elements until an element fails the predicate. The element
466418-- on which the predicate fails is returned back to the input stream.
467419--
468−-- * Stops - when the predicate fails.
420+-- * Stops - when the predicate fails or the collecting fold stops.
469421-- * Fails - never.
470422--
471423-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
@@ -491,9 +443,19 @@ takeWhile cond = K.toParserK . D.takeWhile cond
491443takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
492444takeWhile1 cond = K.toParserK . D.takeWhile1 cond
493445
494−-- | Like 'sliceSepBy' but uses a 'Parser' instead of a 'Fold' to collect the
495−-- input. @sliceSepByP cond parser@ parses a slice of the input using @parser@
496−-- until @cond@ succeeds or the parser stops.
446+-- | Drain the input as long as the predicate succeeds, running the effects and
447+-- discarding the results.
448+--
449+-- This is also called @skipWhile@ in some parsing libraries.
450+--
451+-- /Internal/
452+--
453+{-# INLINE drainWhile #-}
454+drainWhile :: MonadCatch m => (a -> Bool) -> Parser m a ()
455+drainWhile p = takeWhile p FL.drain
456+
457+-- | @sliceSepBy cond parser@ parses a slice of the input using @parser@ until
458+-- @cond@ succeeds or the parser stops.
497459--
498460-- This is a generalized slicing parser which can be used to implement other
499461-- parsers e.g.:
@@ -505,59 +467,10 @@ takeWhile1 cond = K.toParserK . D.takeWhile1 cond
505467--
506468-- /Unimplemented/
507469--
508−{-# INLINABLE sliceSepByP #-}
509−sliceSepByP :: -- MonadCatch m =>
510− (a -> Bool) -> Parser m a b -> Parser m a b
511−sliceSepByP _cond = undefined -- K.toParserK . D.sliceSepByP cond
512−
513−-- Note: Keep this consistent with S.splitOn. In fact we should eliminate
514−-- S.splitOn in favor of the parser.
515−--
516−-- | Split on an infixed separator element, dropping the separator. Splits the
517−-- stream on separator elements determined by the supplied predicate, separator
518−-- is considered as infixed between two segments, if one side of the separator
519−-- is missing then it is parsed as an empty stream. The supplied 'Fold' is
520−-- applied on the split segments. With '-' representing non-separator elements
521−-- and '.' as separator, 'splitOn' splits as follows:
522−--
523−-- @
524−-- "--.--" => "--" "--"
525−-- "--." => "--" ""
526−-- ".--" => "" "--"
527−-- @
528−--
529−-- @PR.sliceSepBy (== x)@ is an inverse of @S.intercalate (S.yield x)@
530−--
531−-- Let's use the following definition for illustration:
532−--
533−-- > splitOn p = PR.many FL.toList $ PR.sliceSepBy p (FL.toList)
534−-- > splitOn' p = S.parse (splitOn p) . S.fromList
535−--
536−-- >>> splitOn' (== '.') ""
537−-- [""]
538−--
539−-- >>> splitOn' (== '.') "."
540−-- ["",""]
541−--
542−-- >>> splitOn' (== '.') ".a"
543−-- > ["","a"]
544−--
545−-- >>> splitOn' (== '.') "a."
546−-- > ["a",""]
547−--
548−-- >>> splitOn' (== '.') "a.b"
549−-- > ["a","b"]
550−--
551−-- >>> splitOn' (== '.') "a..b"
552−-- > ["a","","b"]
553−--
554−-- * Stops - when the predicate succeeds.
555−-- * Fails - never.
556−--
557−-- /Internal/
558470{-# INLINABLE sliceSepBy #-}
559−sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
560−sliceSepBy cond = K.toParserK . D.sliceSepBy cond
471+sliceSepBy :: -- MonadCatch m =>
472+ (a -> Bool) -> Parser m a b -> Parser m a b
473+sliceSepBy _cond = undefined -- K.toParserK . D.sliceSepBy cond
561474
562475-- | Like 'sliceSepBy' but does not drop the separator element, instead
563476-- separator is emitted as a separate element in the output.
@@ -568,23 +481,6 @@ sliceSepWith :: -- MonadCatch m =>
568481 (a -> Bool) -> Fold m a b -> Parser m a b
569482sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond
570483
571−-- | Collect stream elements until an element succeeds the predicate. Also take
572−-- the element on which the predicate succeeded. The succeeding element is
573−-- treated as a suffix separator which is kept in the output segement.
574−--
575−-- * Stops - when the predicate succeeds.
576−-- * Fails - never.
577−--
578−-- S.splitWithSuffix pred f = S.parseMany (PR.sliceEndWith pred f)
579−--
580−-- /Unimplemented/
581−--
582−{-# INLINABLE sliceEndWith #-}
583−sliceEndWith ::
584− -- Monad m =>
585− (a -> Bool) -> Fold m a b -> Parser m a b
586−sliceEndWith = undefined
587−
588484-- | Collect stream elements until an elements passes the predicate, return the
589485-- last element on which the predicate succeeded back to the input stream. If
590486-- the predicate succeeds on the first element itself then it is kept in the
@@ -604,44 +500,6 @@ sliceBeginWith ::
604500 (a -> Bool) -> Fold m a b -> Parser m a b
605501sliceBeginWith = undefined
606502
607−-- | Like 'sliceSepBy' but terminates a parse even before the separator
608−-- is encountered if its size exceeds the specified maximum limit.
609−--
610−-- > take n = PR.sliceSepByMax (const True) n
611−-- > sliceSepBy p = PR.sliceSepByMax p maxBound
612−--
613−-- Let's use the following definitions for illustration:
614−--
615−-- > splitOn p n = PR.many FL.toList $ PR.sliceSepByMax p n (FL.toList)
616−-- > splitOn' p n = S.parse (splitOn p n) . S.fromList
617−--
618−-- >>> splitOn' (== '.') 0 ""
619−-- [""]
620−--
621−-- >>> splitOn' (== '.') 0 "a"
622−-- infinite list of empty strings
623−--
624−-- >>> splitOn' (== '.') 3 "hello.world"
625−-- ["hel","lo","wor","ld"]
626−--
627−-- If the separator is found and the limit is reached at the same time then it
628−-- behaves just like 'sliceSepBy' i.e. the separator is dropped.
629−--
630−-- >>> splitOn' (== '.') 0 "."
631−-- ["",""]
632−--
633−-- >>> splitOn' (== '.') 0 ".."
634−-- ["","",""]
635−--
636−-- * Stops - when the predicate succeeds or the limit is reached.
637−-- * Fails - never.
638−--
639−-- /Internal/
640−{-# INLINABLE sliceSepByMax #-}
641−sliceSepByMax :: MonadCatch m
642− => (a -> Bool) -> Int -> Fold m a b -> Parser m a b
643−sliceSepByMax cond cnt = K.toParserK . D.sliceSepByMax cond cnt
644−
645503-- | Like 'sliceSepBy' but the separator elements can be escaped using an
646504-- escape char determined by the second predicate.
647505--
@@ -911,18 +769,19 @@ deintercalate = undefined
911769-- Sequential Collection
912770-------------------------------------------------------------------------------
913771--
914−-- | @sequence f t@ collects sequential parses of parsers in the container @t@
915−-- using the fold @f@. Fails if the input ends or any of the parsers fail.
772+-- | @concatSequence f t@ collects sequential parses of parsers in the
773+-- container @t@ using the fold @f@. Fails if the input ends or any of the
774+-- parsers fail.
916775--
917776-- This is same as 'Data.Traversable.sequence' but more efficient.
918777--
919778-- /Unimplemented/
920779--
921−{-# INLINE sequence #-}
922−sequence ::
780+{-# INLINE concatSequence #-}
781+concatSequence ::
923782 -- Foldable t =>
924783 Fold m b c -> t (Parser m a b) -> Parser m a c
925−sequence _f _p = undefined
784+concatSequence _f _p = undefined
926785
927786-- | Map a 'Parser' returning function on the result of a 'Parser'.
928787--
@@ -974,10 +833,11 @@ manyP :: -- MonadCatch m =>
974833 Parser m b c -> Parser m a b -> Parser m a c
975834manyP _f _p = undefined -- K.toParserK $ D.manyP f (K.fromParserK p)
976835
977−-- | Collect zero or more parses. Apply the parser repeatedly on the input
978−-- stream, stop when the parser fails, accumulate zero or more parse results
979−-- using the supplied 'Fold'. This parser never fails, in case the first
980−-- application of parser fails it returns an empty result.
836+-- | Collect zero or more parses. Apply the supplied parser repeatedly on the
837+-- input stream and push the parse results to a downstream fold.
838+--
839+-- Stops: when the downstream fold stops or the parser fails.
840+-- Fails: never, produces zero or more results.
981841--
982842-- Compare with 'Control.Applicative.many'.
983843--
@@ -988,10 +848,15 @@ many :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
988848many f p = K.toParserK $ D.many f (K.fromParserK p)
989849-- many = countBetween 0 maxBound
990850
851+-- Note: many1 would perhaps be a better name for this and consistent with
852+-- other names like takeWhile1. But we retain the name "some" for
853+-- compatibility.
854+--
991855-- | Collect one or more parses. Apply the supplied parser repeatedly on the
992−-- input stream and accumulate the parse results as long as the parser
993−-- succeeds, stop when it fails. This parser fails if not even one result is
994−-- collected.
856+-- input stream and push the parse results to a downstream fold.
857+--
858+-- Stops: when the downstream fold stops or the parser fails.
859+-- Fails: if it stops without producing a single result.
995860--
996861-- @some fld parser = many (takeGE 1 fld) parser@
997862--
@@ -1054,6 +919,8 @@ manyTillP _f _p1 _p2 = undefined
1054919-- @test@ is discarded and the output of @collect@ is accumulated by the
1055920-- supplied fold. The parser fails if @collect@ fails.
1056921--
922+-- Stops when the fold @f@ stops.
923+--
1057924-- /Internal/
1058925--
1059926{-# INLINE manyTill #-}