@@ -252,6 +252,7 @@ import Streamly.Internal.Data.Fold.Type (Fold(..))
252import Streamly.Internal.Data.Parser.ParserK.Type (Parser)
252import Streamly.Internal.Data.Parser.ParserK.Type (Parser)
253import Streamly.Internal.Data.Stream.Type (Stream)
253import Streamly.Internal.Data.Stream.Type (Stream)
255+import qualified Data.Foldable as Foldable
255import qualified Streamly.Internal.Data.Fold.Type as FL
256import qualified Streamly.Internal.Data.Fold.Type as FL
256import qualified Streamly.Internal.Data.Parser.ParserD as D
257import qualified Streamly.Internal.Data.Parser.ParserD as D
257import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
258import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
@@ -268,6 +269,7 @@ import Prelude hiding
268-- >>> import Control.Applicative ((<|>))
269-- >>> import Control.Applicative ((<|>))
269-- >>> import Data.Char (isSpace)
270-- >>> import Data.Char (isSpace)
270-- >>> import qualified Data.Maybe as Maybe
271-- >>> import qualified Data.Maybe as Maybe
272+-- >>> import qualified Data.Foldable as Foldable
271-- >>> import qualified Streamly.Data.Stream as Stream
273-- >>> import qualified Streamly.Data.Stream as Stream
272-- >>> import qualified Streamly.Internal.Data.Stream as Stream (parse, parseMany)
274-- >>> import qualified Streamly.Internal.Data.Stream as Stream (parse, parseMany)
273-- >>> import qualified Streamly.Internal.Data.Fold as Fold
275-- >>> import qualified Streamly.Internal.Data.Fold as Fold
@@ -378,6 +380,7 @@ lmapM f p = D.toParserK $ D.lmapM f $ D.fromParserK p
379-- | @rmapM f parser@ maps the monadic function @f@ on the output of the parser.
381-- | @rmapM f parser@ maps the monadic function @f@ on the output of the parser.
381{-# INLINE rmapM #-}
384{-# INLINE rmapM #-}
382rmapM :: Monad m => (b -> m c) -> Parser m a b -> Parser m a c
385rmapM :: Monad m => (b -> m c) -> Parser m a b -> Parser m a c
383rmapM f p = D.toParserK $ D.rmapM f $ D.fromParserK p
386rmapM f p = D.toParserK $ D.rmapM f $ D.fromParserK p
@@ -457,10 +460,10 @@ oneNotEq x = satisfy (/= x)
458-- | Match any one of the elements in the supplied list.
461-- | Match any one of the elements in the supplied list.
460−-- >>> oneOf xs = Parser.satisfy (`elem` xs)
463+-- >>> oneOf xs = Parser.satisfy (`Foldable.elem` xs)
462-- When performance matters a pattern matching predicate could be more
465-- When performance matters a pattern matching predicate could be more
463−-- efficient than a list:
466+-- efficient than a 'Foldable' datatype:
466-- let p x =
469-- let p x =
@@ -476,16 +479,16 @@ oneNotEq x = satisfy (/= x)
476-- search.
479-- search.
478{-# INLINE oneOf #-}
481{-# INLINE oneOf #-}
479−oneOf :: (Monad m, Eq a) => [a] -> Parser m a a
482+oneOf :: (Monad m, Eq a, Foldable f) => f a -> Parser m a a
480−oneOf xs = satisfy (`elem` xs)
483+oneOf xs = satisfy (`Foldable.elem` xs)
482-- | See performance notes in 'oneOf'.
485-- | See performance notes in 'oneOf'.
484−-- >>> noneOf xs = Parser.satisfy (`notElem` xs)
487+-- >>> noneOf xs = Parser.satisfy (`Foldable.notElem` xs)
486{-# INLINE noneOf #-}
489{-# INLINE noneOf #-}
487−noneOf :: (Monad m, Eq a) => [a] -> Parser m a a
490+noneOf :: (Monad m, Eq a, Foldable f) => f a -> Parser m a a
488−noneOf xs = satisfy (`notElem` xs)
491+noneOf xs = satisfy (`Foldable.notElem` xs)
490-- | Return the next element of the input. Returns 'Nothing'
493-- | Return the next element of the input. Returns 'Nothing'
491-- on end of input. Also known as 'head'.
494-- on end of input. Also known as 'head'.
@@ -1008,6 +1011,7 @@ listEqBy cmp xs = D.toParserK (D.listEqBy cmp xs)
1008-- | Like 'listEqBy' but uses a stream instead of a list and does not return
1011-- | Like 'listEqBy' but uses a stream instead of a list and does not return
1009-- the stream.
1012-- the stream.
1014+-- Note: A @Stream m a@ isn't returned as it isn't buffered.
1011{-# INLINE eqBy #-}
1015{-# INLINE eqBy #-}
1012eqBy :: Monad m => (a -> a -> Bool) -> Stream m a -> Parser m a ()
1016eqBy :: Monad m => (a -> a -> Bool) -> Stream m a -> Parser m a ()
1013eqBy cmp = D.toParserK . D.eqBy cmp . Stream.toStreamD
1017eqBy cmp = D.toParserK . D.eqBy cmp . Stream.toStreamD
@@ -1348,17 +1352,21 @@ manyTillP :: -- Monad m =>
1348manyTillP _p1 _p2 _f = undefined
1352manyTillP _p1 _p2 _f = undefined
1349 -- D.toParserK $ D.manyTillP (D.fromParserK p1) (D.fromParserK p2) f
1353 -- D.toParserK $ D.manyTillP (D.fromParserK p1) (D.fromParserK p2) f
1351−-- | @manyTill collect test f@ tries the parser @test@ on the input, if @test@
1355+-- | @manyTill chunking test f@ tries the parser @test@ on the input, if @test@
1352−-- fails it backtracks and tries @collect@, after @collect@ succeeds @test@ is
1356+-- fails it backtracks and tries @chunking@, after @chunking@ succeeds @test@ is
1353-- tried again and so on. The parser stops when @test@ succeeds. The output of
1357-- tried again and so on. The parser stops when @test@ succeeds. The output of
1354−-- @test@ is discarded and the output of @collect@ is accumulated by the
1358+-- @test@ is discarded and the output of @chunking@ is accumulated by the
1355−-- supplied fold. The parser fails if @collect@ fails.
1359+-- supplied fold. The parser fails if @chunking@ fails.
1357-- Stops when the fold @f@ stops.
1361-- Stops when the fold @f@ stops.
1359{-# INLINE manyTill #-}
1363{-# INLINE manyTill #-}
1360manyTill :: Monad m
1364manyTill :: Monad m
1365+ => Parser m a b -- ^ Chunking parser. Parses chunks of input.
1366+ -> Parser m a x -- ^ Test parser. Parsing stops when this parser succeeds
1367+ -- else backtract and run the chunking parser.
1368+ -> Fold m b c -- ^ Folds the output of the chunking parser.
1361− => Parser m a b -> Parser m a x -> Fold m b c -> Parser m a c
1369+ -> Parser m a c
1362manyTill collect test f =
1370manyTill collect test f =
1363 D.toParserK $ D.manyTill (D.fromParserK collect) (D.fromParserK test) f
1371 D.toParserK $ D.manyTill (D.fromParserK collect) (D.fromParserK test) f
@@ -1402,8 +1410,6 @@ manyThen _parser _recover _f = undefined
1402-- considered an interleaving of two patterns. The two parsers represent the
1410-- considered an interleaving of two patterns. The two parsers represent the
1403-- two patterns.
1411-- two patterns.
1405−-- This undoes a "gintercalate" of two streams.
1407{-# INLINE deintercalate #-}
1413{-# INLINE deintercalate #-}
1408deintercalate :: Monad m =>
1414deintercalate :: Monad m =>
1409 Parser m a x
1415 Parser m a x
@@ -1423,8 +1429,8 @@ deintercalate contentL contentR sink =
1424{-# INLINE sepBy1 #-}
1430{-# INLINE sepBy1 #-}
1425sepBy1 :: Monad m =>
1431sepBy1 :: Monad m =>
1426− Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1432+ Parser m a b -> Parser m a x -> Fold m b c -> Parser m a c
1427−sepBy1 sink p sep = do
1433+sepBy1 p sep sink = do
1429 f <- fromEffect $ FL.initialize sink
1435 f <- fromEffect $ FL.initialize sink
1430 f1 <- fromEffect $ FL.snoc f x
1436 f1 <- fromEffect $ FL.snoc f x
@@ -1434,8 +1440,8 @@ sepBy1 sink p sep = do
1434-- run, when it is done content parser is run again and so on. If none of the
1440-- run, when it is done content parser is run again and so on. If none of the
1435-- parsers consumes an input then parser returns a failure.
1441-- parsers consumes an input then parser returns a failure.
1437−-- >>> sepBy sink p1 p2 = Parser.deintercalate p1 p2 (Fold.lefts sink)
1443+-- >>> sepBy p1 p2 sink = Parser.deintercalate p1 p2 (Fold.lefts sink)
1438−-- >>> sepBy sink content sep = Parser.sepBy1 sink content sep <|> return mempty
1444+-- >>> sepBy content sep sink = Parser.sepBy1 content sep sink <|> return mempty
1440{-# INLINE sepBy #-}
1446{-# INLINE sepBy #-}
1441sepBy :: Monad m =>
1447sepBy :: Monad m =>