@@ -54,8 +54,6 @@ module Streamly.Internal.Data.Parser
54 -- First order parsers
54 -- First order parsers
55 -- * Accumulators
55 -- * Accumulators
56 , fromFold
56 , fromFold
@@ -75,8 +73,7 @@ module Streamly.Internal.Data.Parser
76 -- | Grab a sequence of input elements without inspecting them
74 -- | Grab a sequence of input elements without inspecting them
77 , takeBetween
75 , takeBetween
78− , take -- takeBetween 0 n
76+ -- , take -- takeBetween 0 n
80 , takeEQ -- takeBetween n n
77 , takeEQ -- takeBetween n n
81 , takeGE -- takeBetween n maxBound
78 , takeGE -- takeBetween n maxBound
@@ -86,11 +83,9 @@ module Streamly.Internal.Data.Parser
86 , takeWhile
83 , takeWhile
87 -- $takeWhile
84 -- $takeWhile
88 , takeWhile1
85 , takeWhile1
91 , sliceSepBy
88 , sliceSepBy
94 , sliceBeginWith
89 , sliceBeginWith
95 , sliceSepWith
90 , sliceSepWith
96 , escapedSliceSepBy
91 , escapedSliceSepBy
@@ -134,7 +129,7 @@ module Streamly.Internal.Data.Parser
135 -- * N-ary Combinators
130 -- * N-ary Combinators
136 -- ** Sequential Collection
131 -- ** Sequential Collection
137− , sequence
132+ , concatSequence
138 , concatMap
133 , concatMap
140 -- ** Sequential Repetition
135 -- ** Sequential Repetition
@@ -206,6 +201,7 @@ import Prelude
206import Streamly.Internal.Data.Fold.Types (Fold(..))
201import Streamly.Internal.Data.Fold.Types (Fold(..))
207import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
202import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
204+import qualified Streamly.Internal.Data.Fold as FL
209import qualified Streamly.Internal.Data.Parser.ParserD as D
205import qualified Streamly.Internal.Data.Parser.ParserD as D
210import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
206import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
@@ -225,22 +221,6 @@ fromFold = K.toParserK . D.fromFold
225-- Terminating but not failing folds
221-- Terminating but not failing folds
226-------------------------------------------------------------------------------
222-------------------------------------------------------------------------------
229−-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
233−any :: MonadCatch m => (a -> Bool) -> Parser m a Bool
234−any = K.toParserK . D.any
237−-- >>> S.parse (PR.all (== 0)) $ S.fromList [1,0,1]
241−all :: MonadCatch m => (a -> Bool) -> Parser m a Bool
242−all = K.toParserK . D.all
244-- This is the dual of stream "yield".
224-- This is the dual of stream "yield".
246-- | A parser that always yields a pure value without consuming any input.
226-- | A parser that always yields a pure value without consuming any input.
@@ -377,35 +357,6 @@ takeBetween :: -- MonadCatch m =>
377 Int -> Int -> Fold m a b -> Parser m a b
357 Int -> Int -> Fold m a b -> Parser m a b
378takeBetween _m _n = undefined -- K.toParserK . D.takeBetween m n
358takeBetween _m _n = undefined -- K.toParserK . D.takeBetween m n
382−-- Note: this is called takeP in some parser libraries.
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".
388−-- | Take at most @n@ input elements and fold them using the supplied fold.
390−-- Stops after @n@ elements.
393−-- >>> S.parse (PR.take 1 FL.toList) $ S.fromList [1]
396−-- >>> S.parse (PR.take (-1) FL.toList) $ S.fromList [1]
400−-- S.chunksOf n f = S.parseMany (FL.take n f)
406−take :: MonadCatch m => Int -> Fold m a b -> Parser m a b
407−take n = K.toParserK . D.take n
409-- | Stops after taking exactly @n@ input elements.
360-- | Stops after taking exactly @n@ input elements.
411-- * Stops - after consuming @n@ elements.
362-- * Stops - after consuming @n@ elements.
@@ -423,8 +374,9 @@ takeEQ n = K.toParserK . D.takeEQ n
424-- | Take at least @n@ input elements, but can collect more.
375-- | Take at least @n@ input elements, but can collect more.
426−-- * Stops - never.
377+-- * Stops - when the collecting fold stops.
427−-- * Fails - if the stream end before producing @n@ elements.
378+-- * Fails - if the stream or the collecting fold ends before producing @n@
429-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
381-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
430-- > "takeGE: Expecting at least 4 elements, got only 3"
382-- > "takeGE: Expecting at least 4 elements, got only 3"
@@ -465,7 +417,7 @@ takeWhileP _cond = undefined -- K.toParserK . D.takeWhileP cond
465-- | Collect stream elements until an element fails the predicate. The element
417-- | Collect stream elements until an element fails the predicate. The element
466-- on which the predicate fails is returned back to the input stream.
418-- on which the predicate fails is returned back to the input stream.
468−-- * Stops - when the predicate fails.
420+-- * Stops - when the predicate fails or the collecting fold stops.
469-- * Fails - never.
421-- * Fails - never.
471-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
423-- >>> 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
491takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
443takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
492takeWhile1 cond = K.toParserK . D.takeWhile1 cond
444takeWhile1 cond = K.toParserK . D.takeWhile1 cond
494−-- | Like 'sliceSepBy' but uses a 'Parser' instead of a 'Fold' to collect the
446+-- | Drain the input as long as the predicate succeeds, running the effects and
447+-- discarding the results.
449+-- This is also called @skipWhile@ in some parsing libraries.
453+{-# INLINE drainWhile #-}
454+drainWhile :: MonadCatch m => (a -> Bool) -> Parser m a ()
455+drainWhile p = takeWhile p FL.drain
495−-- input. @sliceSepByP cond parser@ parses a slice of the input using @parser@
457+-- | @sliceSepBy cond parser@ parses a slice of the input using @parser@ until
496−-- until @cond@ succeeds or the parser stops.
458+-- @cond@ succeeds or the parser stops.
498-- This is a generalized slicing parser which can be used to implement other
460-- This is a generalized slicing parser which can be used to implement other
499-- parsers e.g.:
461-- parsers e.g.:
@@ -505,59 +467,10 @@ takeWhile1 cond = K.toParserK . D.takeWhile1 cond
506-- /Unimplemented/
468-- /Unimplemented/
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
513−-- Note: Keep this consistent with S.splitOn. In fact we should eliminate
514−-- S.splitOn in favor of the parser.
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:
524−-- "--.--" => "--" "--"
529−-- @PR.sliceSepBy (== x)@ is an inverse of @S.intercalate (S.yield x)@
531−-- Let's use the following definition for illustration:
533−-- > splitOn p = PR.many FL.toList $ PR.sliceSepBy p (FL.toList)
534−-- > splitOn' p = S.parse (splitOn p) . S.fromList
536−-- >>> splitOn' (== '.') ""
539−-- >>> splitOn' (== '.') "."
542−-- >>> splitOn' (== '.') ".a"
545−-- >>> splitOn' (== '.') "a."
548−-- >>> splitOn' (== '.') "a.b"
551−-- >>> splitOn' (== '.') "a..b"
554−-- * Stops - when the predicate succeeds.
558{-# INLINABLE sliceSepBy #-}
470{-# INLINABLE sliceSepBy #-}
559−sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
471+sliceSepBy :: -- MonadCatch m =>
472+ (a -> Bool) -> Parser m a b -> Parser m a b
560−sliceSepBy cond = K.toParserK . D.sliceSepBy cond
473+sliceSepBy _cond = undefined -- K.toParserK . D.sliceSepBy cond
562-- | Like 'sliceSepBy' but does not drop the separator element, instead
475-- | Like 'sliceSepBy' but does not drop the separator element, instead
563-- separator is emitted as a separate element in the output.
476-- separator is emitted as a separate element in the output.
@@ -568,23 +481,6 @@ sliceSepWith :: -- MonadCatch m =>
568 (a -> Bool) -> Fold m a b -> Parser m a b
481 (a -> Bool) -> Fold m a b -> Parser m a b
569sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond
482sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond
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.
575−-- * Stops - when the predicate succeeds.
578−-- S.splitWithSuffix pred f = S.parseMany (PR.sliceEndWith pred f)
582−{-# INLINABLE sliceEndWith #-}
585− (a -> Bool) -> Fold m a b -> Parser m a b
586−sliceEndWith = undefined
588-- | Collect stream elements until an elements passes the predicate, return the
484-- | Collect stream elements until an elements passes the predicate, return the
589-- last element on which the predicate succeeded back to the input stream. If
485-- last element on which the predicate succeeded back to the input stream. If
590-- the predicate succeeds on the first element itself then it is kept in the
486-- the predicate succeeds on the first element itself then it is kept in the
@@ -604,44 +500,6 @@ sliceBeginWith ::
604 (a -> Bool) -> Fold m a b -> Parser m a b
500 (a -> Bool) -> Fold m a b -> Parser m a b
605sliceBeginWith = undefined
501sliceBeginWith = undefined
607−-- | Like 'sliceSepBy' but terminates a parse even before the separator
608−-- is encountered if its size exceeds the specified maximum limit.
610−-- > take n = PR.sliceSepByMax (const True) n
611−-- > sliceSepBy p = PR.sliceSepByMax p maxBound
613−-- Let's use the following definitions for illustration:
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
618−-- >>> splitOn' (== '.') 0 ""
621−-- >>> splitOn' (== '.') 0 "a"
622−-- infinite list of empty strings
624−-- >>> splitOn' (== '.') 3 "hello.world"
625−-- ["hel","lo","wor","ld"]
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.
630−-- >>> splitOn' (== '.') 0 "."
633−-- >>> splitOn' (== '.') 0 ".."
636−-- * Stops - when the predicate succeeds or the limit is reached.
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
645-- | Like 'sliceSepBy' but the separator elements can be escaped using an
503-- | Like 'sliceSepBy' but the separator elements can be escaped using an
646-- escape char determined by the second predicate.
504-- escape char determined by the second predicate.
@@ -911,18 +769,19 @@ deintercalate = undefined
911-- Sequential Collection
769-- Sequential Collection
912-------------------------------------------------------------------------------
770-------------------------------------------------------------------------------
914−-- | @sequence f t@ collects sequential parses of parsers in the container @t@
772+-- | @concatSequence f t@ collects sequential parses of parsers in the
915−-- using the fold @f@. Fails if the input ends or any of the parsers fail.
773+-- container @t@ using the fold @f@. Fails if the input ends or any of the
917-- This is same as 'Data.Traversable.sequence' but more efficient.
776-- This is same as 'Data.Traversable.sequence' but more efficient.
919-- /Unimplemented/
778-- /Unimplemented/
921−{-# INLINE sequence #-}
780+{-# INLINE concatSequence #-}
922−sequence ::
781+concatSequence ::
923 -- Foldable t =>
782 -- Foldable t =>
924 Fold m b c -> t (Parser m a b) -> Parser m a c
783 Fold m b c -> t (Parser m a b) -> Parser m a c
925−sequence _f _p = undefined
784+concatSequence _f _p = undefined
927-- | Map a 'Parser' returning function on the result of a 'Parser'.
786-- | Map a 'Parser' returning function on the result of a 'Parser'.
@@ -974,10 +833,11 @@ manyP :: -- MonadCatch m =>
974 Parser m b c -> Parser m a b -> Parser m a c
833 Parser m b c -> Parser m a b -> Parser m a c
975manyP _f _p = undefined -- K.toParserK $ D.manyP f (K.fromParserK p)
834manyP _f _p = undefined -- K.toParserK $ D.manyP f (K.fromParserK p)
977−-- | Collect zero or more parses. Apply the parser repeatedly on the input
836+-- | Collect zero or more parses. Apply the supplied parser repeatedly on the
978−-- stream, stop when the parser fails, accumulate zero or more parse results
837+-- input stream and push the parse results to a downstream fold.
979−-- using the supplied 'Fold'. This parser never fails, in case the first
838+--
980−-- application of parser fails it returns an empty result.
839+-- Stops: when the downstream fold stops or the parser fails.
840+-- Fails: never, produces zero or more results.
982-- Compare with 'Control.Applicative.many'.
842-- Compare with 'Control.Applicative.many'.
@@ -988,10 +848,15 @@ many :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
988many f p = K.toParserK $ D.many f (K.fromParserK p)
848many f p = K.toParserK $ D.many f (K.fromParserK p)
989-- many = countBetween 0 maxBound
849-- many = countBetween 0 maxBound
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
991-- | Collect one or more parses. Apply the supplied parser repeatedly on the
855-- | 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
856+-- input stream and push the parse results to a downstream fold.
993−-- succeeds, stop when it fails. This parser fails if not even one result is
857+--
994−-- collected.
858+-- Stops: when the downstream fold stops or the parser fails.
859+-- Fails: if it stops without producing a single result.
996-- @some fld parser = many (takeGE 1 fld) parser@
861-- @some fld parser = many (takeGE 1 fld) parser@
@@ -1054,6 +919,8 @@ manyTillP _f _p1 _p2 = undefined
1054-- @test@ is discarded and the output of @collect@ is accumulated by the
919-- @test@ is discarded and the output of @collect@ is accumulated by the
1055-- supplied fold. The parser fails if @collect@ fails.
920-- supplied fold. The parser fails if @collect@ fails.
922+-- Stops when the fold @f@ stops.
1057-- /Internal/
924-- /Internal/
1059{-# INLINE manyTill #-}
926{-# INLINE manyTill #-}