@@ -0,0 +1,871 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE RankNTypes #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
4+
5+#if __GLASGOW_HASKELL__ >= 800
6+{-# OPTIONS_GHC -Wno-orphans #-}
7+#endif
8+
9+-- |
10+-- Module : Streamly.Internal.Data.Parser
11+-- Copyright : (c) 2020 Composewell Technologies
12+-- License : BSD3
13+-- Maintainer : streamly@composewell.com
14+-- Stability : experimental
15+-- Portability : GHC
16+--
17+-- Fast backtracking parsers with stream fusion and native streaming
18+-- capability.
19+--
20+-- 'Applicative' and 'Control.Applicative.Alternative' type class based
21+-- combinators from the
22+-- <http://hackage.haskell.org/package/parser-combinators parser-combinators>
23+-- package can also be used with the 'Parser' type. However, there are two
24+-- important differences between @parser-combinators@ and the equivalent ones
25+-- provided in this module in terms of performance:
26+--
27+-- 1) @parser-combinators@ use plain Haskell lists to collect the results, in a
28+-- strict Monad like IO, the results are necessarily buffered before they can
29+-- be consumed. This may not perform optimally in streaming applications
30+-- processing large amounts of data. Equivalent combinators in this module can
31+-- consume the results of parsing using a 'Fold', thus providing a scalability
32+-- and a composable consumer.
33+--
34+-- 2) Several combinators in this module can be many times faster because of
35+-- stream fusion. For example, 'Streamly.Internal.Data.Parser.many' combinator
36+-- in this module is much faster than the 'Control.Applicative.many' combinator
37+-- of 'Control.Applicative.Alternative' type class.
38+--
39+-- = Errors
40+--
41+-- Failing parsers in this module throw the 'D.ParseError' exception.
42+--
43+-- = Naming
44+--
45+-- As far as possible, try that the names of the combinators in this module are
46+-- consistent with:
47+--
48+-- * <https://hackage.haskell.org/package/base/docs/Text-ParserCombinators-ReadP.html base/Text.ParserCombinators.ReadP>
49+-- * <http://hackage.haskell.org/package/parser-combinators parser-combinators>
50+-- * <http://hackage.haskell.org/package/megaparsec megaparsec>
51+-- * <http://hackage.haskell.org/package/attoparsec attoparsec>
52+-- * <http://hackage.haskell.org/package/parsec parsec>
53+
54+module Streamly.Internal.Data.Parser
55+ (
56+ K.Parser (..)
57+ , D.ParseError (..)
58+ , D.Step (..)
59+
60+ -- First order parsers
61+ -- * Accumulators
62+ , fromFold
63+ , any
64+ , all
65+ , yield
66+ , yieldM
67+ , die
68+ , dieM
69+
70+ -- * Element parsers
71+ , peek
72+ , eof
73+ , satisfy
74+
75+ -- * Sequence parsers
76+ --
77+ -- | Parsers chained in series, if one parser terminates the composition
78+ -- terminates.
79+ --
80+ -- TODO: Currently we are using folds to collect the output of the parsers
81+ -- but we can use Parsers instead of folds to make the composition more
82+ -- powerful. For example, we can do:
83+ --
84+ -- @
85+ -- sliceSepByMax cond n p = sliceBy cond (take n p)
86+ -- sliceSepByBetween cond m n p = sliceBy cond (takeBetween m n p)
87+ -- takeWhileBetween cond m n p = takeWhile cond (takeBetween m n p)
88+ -- @
89+ --
90+ -- TODO: Like toList fold we can have toNonEmpty Parser to fold to a
91+ -- nonempty list. If we cannot collect even one element the parser will
92+ -- fail. toNonEmpty can be used in takeWhile to implement takeWhile1.
93+
94+ -- | Grab a sequence of input elements without inspecting them
95+ , take
96+ -- $take
97+ -- | Unimplemented
98+ --
99+ -- @
100+ -- , takeBetween
101+ -- , takeLE -- take -- takeBetween 0 n
102+ -- , takeLE1 -- take1 -- takeBetween 1 n
103+ -- @
104+ , takeEQ -- takeBetween n n
105+ , takeGE -- takeBetween n maxBound
106+
107+ -- Grab a sequence of input elements by inspecting them
108+ , lookAhead
109+ , takeWhile
110+ -- $takeWhile
111+ , takeWhile1
112+ , sliceSepBy
113+ , sliceSepByMax
114+ -- | Unimplemented
115+ --
116+ -- @
117+ -- , sliceSepByBetween
118+ -- @
119+ , sliceEndWith
120+ , sliceBeginWith
121+ -- | Unimplemented
122+ --
123+ -- @
124+ -- , sliceSepWith
125+ --
126+ -- , frameSepBy -- parse frames escaped by an escape char/sequence
127+ -- , frameEndWith
128+ -- @
129+ , wordBy
130+ , groupBy
131+ , eqBy
132+ -- | Unimplemented
133+ --
134+ -- @
135+ -- , prefixOf -- match any prefix of a given string
136+ -- , suffixOf -- match any suffix of a given string
137+ -- , infixOf -- match any substring of a given string
138+ -- @
139+
140+ -- Second order parsers (parsers using parsers)
141+ -- * Binary Combinators
142+
143+ -- ** Sequential Applicative
144+ , splitWith
145+ , split_
146+
147+ -- ** Parallel Applicatives
148+ , teeWith
149+ , teeWithFst
150+ , teeWithMin
151+ -- , teeTill -- like manyTill but parallel
152+
153+ -- ** Sequential Interleaving
154+ -- Use two folds, run a primary parser, its rejected values go to the
155+ -- secondary parser.
156+ , deintercalate
157+
158+ -- ** Sequential Alternative
159+ , alt
160+
161+ -- ** Parallel Alternatives
162+ , shortest
163+ , longest
164+ -- , fastest
165+
166+ -- * N-ary Combinators
167+ -- ** Sequential Collection
168+ , sequence
169+ , concatMap
170+
171+ -- ** Sequential Repetition
172+ , count
173+ , countBetween
174+ -- , countBetweenTill
175+
176+ , many
177+ , some
178+ , manyTill
179+
180+ -- ** Special cases
181+ -- | TODO: traditional implmentations of these may be of limited use. For
182+ -- example, consider parsing lines separated by @\\r\\n@. The main parser
183+ -- will have to detect and exclude the sequence @\\r\\n@ anyway so that we
184+ -- can apply the "sep" parser.
185+ --
186+ -- We can instead implement these as special cases of deintercalate.
187+ --
188+ -- @
189+ -- , endBy
190+ -- , sepBy
191+ -- , sepEndBy
192+ -- , beginBy
193+ -- , sepBeginBy
194+ -- , sepAroundBy
195+ -- @
196+
197+ -- * Distribution
198+ --
199+ -- | A simple and stupid impl would be to just convert the stream to an
200+ -- array and give the array reference to all consumers. The array can be
201+ -- grown on demand by any consumer and truncated when nonbody needs it.
202+
203+ -- ** Distribute to collection
204+ -- ** Distribute to repetition
205+
206+ -- ** Interleaved collection
207+ -- |
208+ --
209+ -- 1. Round robin
210+ -- 2. Priority based
211+
212+ -- ** Interleaved repetition
213+ -- | repeat one parser and when it fails run an error recovery parser
214+ -- e.g. to find a key frame in the stream after an error
215+
216+ -- ** Collection of Alternatives
217+ -- | Unimplemented
218+ --
219+ -- @
220+ -- , shortestN
221+ -- , longestN
222+ -- , fastestN -- first N successful in time
223+ -- , choiceN -- first N successful in position
224+ -- @
225+ , choice -- first successful in position
226+
227+ -- ** Repeated Alternatives
228+ -- |
229+ --
230+ -- @
231+ -- , retryMax -- try N times
232+ -- , retryUntil -- try until successful
233+ -- , retryUntilN -- try until successful n times
234+ -- @
235+ )
236+where
237+
238+import Control.Monad.Catch (MonadCatch)
239+import Prelude
240+ hiding (any, all, take, takeWhile, sequence, concatMap)
241+
242+import Streamly.Internal.Data.Fold.Types (Fold(..))
243+import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
244+
245+import qualified Streamly.Internal.Data.Parser.ParserD as D
246+import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
247+
248+-------------------------------------------------------------------------------
249+-- Upgrade folds to parses
250+-------------------------------------------------------------------------------
251+--
252+-- | Make a 'Parser' from a 'Fold'.
253+--
254+-- /Internal/
255+--
256+{-# INLINE fromFold #-}
257+fromFold :: MonadCatch m => Fold m a b -> Parser m a b
258+fromFold = D.toParserK . D.fromFold
259+
260+-------------------------------------------------------------------------------
261+-- Terminating but not failing folds
262+-------------------------------------------------------------------------------
263+--
264+-- |
265+-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
266+-- > True
267+--
268+{-# INLINE any #-}
269+any :: MonadCatch m => (a -> Bool) -> Parser m a Bool
270+any = D.toParserK . D.any
271+
272+-- |
273+-- >>> S.parse (PR.all (== 0)) $ S.fromList [1,0,1]
274+-- > False
275+--
276+{-# INLINE all #-}
277+all :: MonadCatch m => (a -> Bool) -> Parser m a Bool
278+all = D.toParserK . D.all
279+
280+-- This is the dual of stream "yield".
281+--
282+-- | A parser that always yields a pure value without consuming any input.
283+--
284+-- /Internal/
285+--
286+{-# INLINE [3] yield #-}
287+yield :: MonadCatch m => b -> Parser m a b
288+yield = D.toParserK . D.yield
289+{-# RULES "yield fallback to CPS" [2]
290+ forall a. D.toParserK (D.yield a) = K.yield a #-}
291+
292+-- This is the dual of stream "yieldM".
293+--
294+-- | A parser that always yields the result of an effectful action without
295+-- consuming any input.
296+--
297+-- /Internal/
298+--
299+{-# INLINE yieldM #-}
300+yieldM :: MonadCatch m => m b -> Parser m a b
301+yieldM = D.toParserK . D.yieldM
302+
303+-- This is the dual of "nil".
304+--
305+-- | A parser that always fails with an error message without consuming
306+-- any input.
307+--
308+-- /Internal/
309+--
310+{-# INLINE [3] die #-}
311+die :: MonadCatch m => String -> Parser m a b
312+die = D.toParserK . D.die
313+{-# RULES "die fallback to CPS" [2]
314+ forall a. D.toParserK (D.die a) = K.die a #-}
315+
316+-- This is the dual of "nilM".
317+--
318+-- | A parser that always fails with an effectful error message and without
319+-- consuming any input.
320+--
321+-- /Internal/
322+--
323+{-# INLINE dieM #-}
324+dieM :: MonadCatch m => m String -> Parser m a b
325+dieM = D.toParserK . D.dieM
326+
327+-------------------------------------------------------------------------------
328+-- Failing Parsers
329+-------------------------------------------------------------------------------
330+
331+-- | Peek the head element of a stream, without consuming it. Fails if it
332+-- encounters end of input.
333+--
334+-- >>> S.parse ((,) <$> PR.peek <*> PR.satisfy (> 0)) $ S.fromList [1]
335+-- (1,1)
336+--
337+-- @
338+-- peek = lookAhead (satisfy True)
339+-- @
340+--
341+-- /Internal/
342+--
343+{-# INLINE peek #-}
344+peek :: MonadCatch m => Parser m a a
345+peek = D.toParserK D.peek
346+
347+-- | Succeeds if we are at the end of input, fails otherwise.
348+--
349+-- >>> S.parse ((,) <$> PR.satisfy (> 0) <*> PR.eof) $ S.fromList [1]
350+-- > (1,())
351+--
352+-- /Internal/
353+--
354+{-# INLINE eof #-}
355+eof :: MonadCatch m => Parser m a ()
356+eof = D.toParserK D.eof
357+
358+-- | Returns the next element if it passes the predicate, fails otherwise.
359+--
360+-- >>> S.parse (PR.satisfy (== 1)) $ S.fromList [1,0,1]
361+-- > 1
362+--
363+-- /Internal/
364+--
365+{-# INLINE satisfy #-}
366+satisfy :: MonadCatch m => (a -> Bool) -> Parser m a a
367+satisfy = D.toParserK . D.satisfy
368+
369+-------------------------------------------------------------------------------
370+-- Taking elements
371+-------------------------------------------------------------------------------
372+--
373+-- $take
374+-- Note: this is called takeP in some parser libraries.
375+--
376+-- TODO Once we have terminating folds, this Parse should get replaced by Fold.
377+-- Alternatively, we can name it "chunkOf" and the corresponding time domain
378+-- combinator as "intervalOf" or even "chunk" and "interval".
379+
380+-- | Take at most @n@ input elements and fold them using the supplied fold.
381+--
382+-- Stops after @n@ elements.
383+-- Never fails.
384+--
385+-- >>> S.parse (PR.take 1 FL.toList) $ S.fromList [1]
386+-- [1]
387+--
388+-- @
389+-- S.chunksOf n f = S.splitParse (FL.take n f)
390+-- @
391+--
392+-- /Internal/
393+--
394+{-# INLINE take #-}
395+take :: MonadCatch m => Int -> Fold m a b -> Parser m a b
396+take n = D.toParserK . D.take n
397+
398+-- | Stops after taking exactly @n@ input elements.
399+--
400+-- * Stops - after @n@ elements.
401+-- * Fails - if the stream ends before it can collect @n@ elements.
402+--
403+-- >>> S.parse (PR.takeEQ 4 FL.toList) $ S.fromList [1,0,1]
404+-- > "takeEQ: Expecting exactly 4 elements, got 3"
405+--
406+-- /Internal/
407+--
408+{-# INLINE takeEQ #-}
409+takeEQ :: MonadCatch m => Int -> Fold m a b -> Parser m a b
410+takeEQ n = D.toParserK . D.takeEQ n
411+
412+-- | Take at least @n@ input elements, but can collect more.
413+--
414+-- * Stops - never.
415+-- * Fails - if the stream end before producing @n@ elements.
416+--
417+-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
418+-- > "takeGE: Expecting at least 4 elements, got only 3"
419+--
420+-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1,0,1]
421+-- > [1,0,1,0,1]
422+--
423+-- /Internal/
424+--
425+{-# INLINE takeGE #-}
426+takeGE :: MonadCatch m => Int -> Fold m a b -> Parser m a b
427+takeGE n = D.toParserK . D.takeGE n
428+
429+-- $takeWhile
430+-- Note: This is called @takeWhileP@ and @munch@ in some parser libraries.
431+
432+-- | Collect stream elements until an element fails the predicate. The element
433+-- on which the predicate fails is returned back to the input stream.
434+--
435+-- * Stops - when the predicate fails.
436+-- * Fails - never.
437+--
438+-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
439+-- > [0,0]
440+--
441+-- We can implement a @breakOn@ using 'takeWhile':
442+--
443+-- @
444+-- breakOn p = takeWhile (not p)
445+-- @
446+--
447+-- /Internal/
448+--
449+{-# INLINE takeWhile #-}
450+takeWhile :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
451+takeWhile cond = D.toParserK . D.takeWhile cond
452+
453+-- | Like 'takeWhile' but takes at least one element otherwise fails.
454+--
455+-- /Internal/
456+--
457+{-# INLINE takeWhile1 #-}
458+takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
459+takeWhile1 cond = D.toParserK . D.takeWhile1 cond
460+
461+-- | Collect stream elements until an element succeeds the predicate. Drop the
462+-- element on which the predicate succeeded. The succeeding element is treated
463+-- as an infix separator which is dropped from the output.
464+--
465+-- * Stops - when the predicate succeeds.
466+-- * Fails - never.
467+--
468+-- >>> S.parse (PR.sliceSepBy (== 1) FL.toList) $ S.fromList [0,0,1,0,1]
469+-- > [0,0]
470+--
471+-- S.splitOn pred f = S.splitParse (PR.sliceSepBy pred f)
472+--
473+-- >>> S.toList $ S.splitParse (PR.sliceSepBy (== 1) FL.toList) $ S.fromList [0,0,1,0,1]
474+-- > [[0,0],[0],[]]
475+--
476+-- /Internal/
477+--
478+{-# INLINABLE sliceSepBy #-}
479+sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
480+sliceSepBy cond = D.toParserK . D.sliceSepBy cond
481+
482+-- | Collect stream elements until an element succeeds the predicate. Also take
483+-- the element on which the predicate succeeded. The succeeding element is
484+-- treated as a suffix separator which is kept in the output segement.
485+--
486+-- * Stops - when the predicate succeeds.
487+-- * Fails - never.
488+--
489+-- S.splitWithSuffix pred f = S.splitParse (PR.sliceEndWith pred f)
490+--
491+-- /Unimplemented/
492+--
493+{-# INLINABLE sliceEndWith #-}
494+sliceEndWith ::
495+ -- Monad m =>
496+ (a -> Bool) -> Fold m a b -> Parser m a b
497+sliceEndWith = undefined
498+
499+-- | Collect stream elements until an elements passes the predicate, return the
500+-- last element on which the predicate succeeded back to the input stream. If
501+-- the predicate succeeds on the first element itself then it is kept in the
502+-- stream and we continue collecting. The succeeding element is treated as a
503+-- prefix separator which is kept in the output segement.
504+--
505+-- * Stops - when the predicate succeeds in non-leading position.
506+-- * Fails - never.
507+--
508+-- S.splitWithPrefix pred f = S.splitParse (PR.sliceBeginWith pred f)
509+--
510+-- /Unimplemented/
511+--
512+{-# INLINABLE sliceBeginWith #-}
513+sliceBeginWith ::
514+ -- Monad m =>
515+ (a -> Bool) -> Fold m a b -> Parser m a b
516+sliceBeginWith = undefined
517+
518+-- | Split using a condition or a count whichever occurs first. This is a
519+-- hybrid of 'splitOn' and 'take'. The element on which the condition succeeds
520+-- is dropped.
521+--
522+-- /Internal/
523+--
524+{-# INLINABLE sliceSepByMax #-}
525+sliceSepByMax :: MonadCatch m
526+ => (a -> Bool) -> Int -> Fold m a b -> Parser m a b
527+sliceSepByMax cond cnt = D.toParserK . D.sliceSepByMax cond cnt
528+
529+-- | Like 'splitOn' but strips leading, trailing, and repeated separators.
530+-- Therefore, @".a..b."@ having '.' as the separator would be parsed as
531+-- @["a","b"]@. In other words, its like parsing words from whitespace
532+-- separated text.
533+--
534+-- * Stops - when it finds a word separator after a non-word element
535+-- * Fails - never.
536+--
537+-- @
538+-- S.wordsBy pred f = S.splitParse (PR.wordBy pred f)
539+-- @
540+--
541+-- /Unimplemented/
542+--
543+{-# INLINABLE wordBy #-}
544+wordBy ::
545+ -- Monad m =>
546+ (a -> Bool) -> Fold m a b -> Parser m a b
547+wordBy = undefined
548+
549+-- | @groupBy cmp f $ S.fromList [a,b,c,...]@ assigns the element @a@ to the
550+-- first group, then if @a \`cmp` b@ is 'True' @b@ is also assigned to the same
551+-- group. If @a \`cmp` c@ is 'True' then @c@ is also assigned to the same
552+-- group and so on. When the comparison fails a new group is started. Each
553+-- group is folded using the 'Fold' @f@ and the result of the fold is emitted
554+-- in the output stream.
555+--
556+-- * Stops - when the comparison fails.
557+-- * Fails - never.
558+--
559+-- @
560+-- S.groupsBy cmp f = S.splitParse (PR.groupBy cmp f)
561+-- @
562+--
563+-- /Unimplemented/
564+--
565+{-# INLINABLE groupBy #-}
566+groupBy ::
567+ -- Monad m =>
568+ (a -> a -> Bool) -> Fold m a b -> Parser m a b
569+groupBy = undefined
570+
571+-- | Match the given sequence of elements using the given comparison function.
572+--
573+-- /Internal/
574+--
575+{-# INLINE eqBy #-}
576+eqBy :: MonadCatch m => (a -> a -> Bool) -> [a] -> Parser m a ()
577+eqBy cmp = D.toParserK . D.eqBy cmp
578+
579+-------------------------------------------------------------------------------
580+-- nested parsers
581+-------------------------------------------------------------------------------
582+
583+-- | Sequential parser application. Apply two parsers sequentially to an input
584+-- stream. The input is provided to the first parser, when it is done the
585+-- remaining input is provided to the second parser. If both the parsers
586+-- succeed their outputs are combined using the supplied function. The
587+-- operation fails if any of the parsers fail.
588+--
589+-- Note: This is a parsing dual of appending streams using
590+-- 'Streamly.Prelude.serial', it splits the streams using two parsers and zips
591+-- the results.
592+--
593+-- This implementation is strict in the second argument, therefore, the
594+-- following will fail:
595+--
596+-- >>> S.parse (PR.splitWith const (PR.satisfy (> 0)) undefined) $ S.fromList [1]
597+--
598+-- Compare with 'Applicative' instance method '<*>'. This implementation allows
599+-- stream fusion but has quadratic complexity. This can fuse with other
600+-- operations and can be faster than 'Applicative' instance for small number
601+-- (less than 8) of compositions.
602+--
603+-- /Internal/
604+--
605+{-# INLINE splitWith #-}
606+splitWith :: MonadCatch m
607+ => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
608+splitWith f p1 p2 =
609+ D.toParserK $ D.splitWith f (D.fromParserK p1) (D.fromParserK p2)
610+
611+-- | Sequential parser application ignoring the output of the first parser.
612+-- Apply two parsers sequentially to an input stream. The input is provided to
613+-- the first parser, when it is done the remaining input is provided to the
614+-- second parser. The output of the parser is the output of the second parser.
615+-- The operation fails if any of the parsers fail.
616+--
617+-- This implementation is strict in the second argument, therefore, the
618+-- following will fail:
619+--
620+-- >>> S.parse (split_ (PR.satisfy (> 0)) undefined) $ S.fromList [1]
621+--
622+-- Compare with 'Applicative' instance method '*>'. This implementation allows
623+-- stream fusion but has quadratic complexity. This can fuse with other
624+-- operations, and can be faster than 'Applicative' instance for small
625+-- number (less than 8) of compositions.
626+--
627+-- /Internal/
628+--
629+{-# INLINE split_ #-}
630+split_ :: MonadCatch m => Parser m x a -> Parser m x b -> Parser m x b
631+split_ p1 p2 = D.toParserK $ D.split_ (D.fromParserK p1) (D.fromParserK p2)
632+
633+-- | @teeWith f p1 p2@ distributes its input to both @p1@ and @p2@ until both
634+-- of them succeed or anyone of them fails and combines their output using @f@.
635+-- The parser succeeds if both the parsers succeed.
636+--
637+-- /Internal/
638+--
639+{-# INLINE teeWith #-}
640+teeWith :: MonadCatch m
641+ => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
642+teeWith f p1 p2 =
643+ D.toParserK $ D.teeWith f (D.fromParserK p1) (D.fromParserK p2)
644+
645+-- | Like 'teeWith' but ends parsing and zips the results, if available,
646+-- whenever the first parser ends.
647+--
648+-- /Internal/
649+--
650+{-# INLINE teeWithFst #-}
651+teeWithFst :: MonadCatch m
652+ => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
653+teeWithFst f p1 p2 =
654+ D.toParserK $ D.teeWithFst f (D.fromParserK p1) (D.fromParserK p2)
655+
656+-- | Like 'teeWith' but ends parsing and zips the results, if available,
657+-- whenever any of the parsers ends or fails.
658+--
659+-- /Unimplemented/
660+--
661+{-# INLINE teeWithMin #-}
662+teeWithMin :: MonadCatch m
663+ => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
664+teeWithMin f p1 p2 =
665+ D.toParserK $ D.teeWithMin f (D.fromParserK p1) (D.fromParserK p2)
666+
667+-- | Sequential alternative. Apply the input to the first parser and return the
668+-- result if the parser succeeds. If the first parser fails then backtrack and
669+-- apply the same input to the second parser and return the result.
670+--
671+-- Note: This implementation is not lazy in the second argument. The following
672+-- will fail:
673+--
674+-- >>> S.parse (PR.satisfy (> 0) `PR.alt` undefined) $ S.fromList [1..10]
675+--
676+-- Compare with 'Alternative' instance method '<|>'. This implementation allows
677+-- stream fusion but has quadratic complexity. This can fuse with other
678+-- operations and can be much faster than 'Alternative' instance for small
679+-- number (less than 8) of alternatives.
680+--
681+-- /Internal/
682+--
683+{-# INLINE alt #-}
684+alt :: MonadCatch m => Parser m x a -> Parser m x a -> Parser m x a
685+alt p1 p2 = D.toParserK $ D.alt (D.fromParserK p1) (D.fromParserK p2)
686+
687+-- | Shortest alternative. Apply both parsers in parallel but choose the result
688+-- from the one which consumed least input i.e. take the shortest succeeding
689+-- parse.
690+--
691+-- /Internal/
692+--
693+{-# INLINE shortest #-}
694+shortest :: MonadCatch m
695+ => Parser m x a -> Parser m x a -> Parser m x a
696+shortest p1 p2 = D.toParserK $ D.shortest (D.fromParserK p1) (D.fromParserK p2)
697+
698+-- | Longest alternative. Apply both parsers in parallel but choose the result
699+-- from the one which consumed more input i.e. take the longest succeeding
700+-- parse.
701+--
702+-- /Internal/
703+--
704+{-# INLINE longest #-}
705+longest :: MonadCatch m
706+ => Parser m x a -> Parser m x a -> Parser m x a
707+longest p1 p2 = D.toParserK $ D.longest (D.fromParserK p1) (D.fromParserK p2)
708+
709+-- | Run a parser without consuming the input.
710+--
711+-- /Internal/
712+--
713+{-# INLINE lookAhead #-}
714+lookAhead :: MonadCatch m => Parser m a b -> Parser m a b
715+lookAhead p = D.toParserK $ D.lookAhead $ D.fromParserK p
716+
717+-------------------------------------------------------------------------------
718+-- Interleaving
719+-------------------------------------------------------------------------------
720+--
721+-- To deinterleave we can chain two parsers one behind the other. The input is
722+-- given to the first parser and the input definitively rejected by the first
723+-- parser is given to the second parser.
724+--
725+-- We can either have the parsers themselves buffer the input or use the shared
726+-- global buffer to hold it until none of the parsers need it. When the first
727+-- parser returns Skip (i.e. rewind) we let the second parser consume the
728+-- rejected input and when it is done we move the cursor forward to the first
729+-- parser again. This will require a "move forward" command as well.
730+--
731+-- To implement grep we can use three parsers, one to find the pattern, one
732+-- to store the context behind the pattern and one to store the context in
733+-- front of the pattern. When a match occurs we need to emit the accumulator of
734+-- all the three parsers. One parser can count the line numbers to provide the
735+-- line number info.
736+--
737+-- | Apply two parsers alternately to an input stream. The input stream is
738+-- considered an interleaving of two patterns. The two parsers represent the
739+-- two patterns.
740+--
741+-- This undoes a "gintercalate" of two streams.
742+--
743+-- /Unimplemented/
744+--
745+{-# INLINE deintercalate #-}
746+deintercalate ::
747+ -- Monad m =>
748+ Fold m a y -> Parser m x a
749+ -> Fold m b z -> Parser m x b
750+ -> Parser m x (y, z)
751+deintercalate = undefined
752+
753+-------------------------------------------------------------------------------
754+-- Sequential Collection
755+-------------------------------------------------------------------------------
756+--
757+-- | @sequence f t@ collects sequential parses of parsers in the container @t@
758+-- using the fold @f@. Fails if the input ends or any of the parsers fail.
759+--
760+-- /Unimplemented/
761+--
762+{-# INLINE sequence #-}
763+sequence ::
764+ -- Foldable t =>
765+ Fold m b c -> t (Parser m a b) -> Parser m a c
766+sequence _f _p = undefined
767+
768+-- | Map a 'Parser' returning function on the result of a 'Parser'.
769+--
770+-- Compare with 'Monad' instance method '>>='. This implementation allows
771+-- stream fusion but has quadratic complexity. This can fuse with other
772+-- operations and can be much faster than 'Monad' instance for small number
773+-- (less than 8) of compositions.
774+--
775+-- /Internal/
776+--
777+{-# INLINE concatMap #-}
778+concatMap :: MonadCatch m
779+ => (b -> Parser m a c) -> Parser m a b -> Parser m a c
780+concatMap f p = D.toParserK $ D.concatMap (D.fromParserK . f) (D.fromParserK p)
781+
782+-------------------------------------------------------------------------------
783+-- Alternative Collection
784+-------------------------------------------------------------------------------
785+--
786+-- | @choice parsers@ applies the @parsers@ in order and returns the first
787+-- successful parse.
788+--
789+{-# INLINE choice #-}
790+choice ::
791+ -- Foldable t =>
792+ t (Parser m a b) -> Parser m a b
793+choice _ps = undefined
794+
795+-------------------------------------------------------------------------------
796+-- Sequential Repetition
797+-------------------------------------------------------------------------------
798+--
799+-- $many
800+-- TODO "many" is essentially a Fold because it cannot fail. So it can be
801+-- downgraded to a Fold. Or we can make the return type a Fold instead and
802+-- upgrade that to a parser when needed.
803+
804+-- | Collect zero or more parses. Apply the parser repeatedly on the input
805+-- stream, stop when the parser fails, accumulate zero or more parse results
806+-- using the supplied 'Fold'. This parser never fails, in case the first
807+-- application of parser fails it returns an empty result.
808+--
809+-- Compare with 'Control.Applicative.many'.
810+--
811+-- /Internal/
812+--
813+{-# INLINE many #-}
814+many :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
815+many f p = D.toParserK $ D.many f (D.fromParserK p)
816+-- many = countBetween 0 maxBound
817+
818+-- | Collect one or more parses. Apply the supplied parser repeatedly on the
819+-- input stream and accumulate the parse results as long as the parser
820+-- succeeds, stop when it fails. This parser fails if not even one result is
821+-- collected.
822+--
823+-- Compare with 'Control.Applicative.some'.
824+--
825+-- /Internal/
826+--
827+{-# INLINE some #-}
828+some :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
829+some f p = D.toParserK $ D.some f (D.fromParserK p)
830+-- some f p = many (takeGE 1 f) p
831+-- many = countBetween 1 maxBound
832+
833+-- | @countBetween m n f p@ collects between @m@ and @n@ sequential parses of
834+-- parser @p@ using the fold @f@. Stop after collecting @n@ results. Fails if
835+-- the input ends or the parser fails before @m@ results are collected.
836+--
837+-- /Unimplemented/
838+--
839+{-# INLINE countBetween #-}
840+countBetween ::
841+ -- MonadCatch m =>
842+ Int -> Int -> Fold m b c -> Parser m a b -> Parser m a c
843+countBetween _m _n _f = undefined
844+-- countBetween m n f p = many (takeBetween m n f) p
845+
846+-- | @count n f p@ collects exactly @n@ sequential parses of parser @p@ using
847+-- the fold @f@. Fails if the input ends or the parser fails before @n@
848+-- results are collected.
849+--
850+-- /Unimplemented/
851+--
852+{-# INLINE count #-}
853+count ::
854+ -- MonadCatch m =>
855+ Int -> Fold m b c -> Parser m a b -> Parser m a c
856+count n = countBetween n n
857+-- count n f p = many (takeEQ n f) p
858+
859+-- | @manyTill f collect test@ tries the parser @test@ on the input, if @test@
860+-- fails it backtracks and tries @collect@, after @collect@ succeeds @test@ is
861+-- tried again and so on. The parser stops when @test@ succeeds. The output of
862+-- @test@ is discarded and the output of @collect@ is accumulated by the
863+-- supplied fold. The parser fails if @collect@ fails.
864+--
865+-- /Internal/
866+--
867+{-# INLINE manyTill #-}
868+manyTill :: MonadCatch m
869+ => Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
870+manyTill f p1 p2 =
871+ D.toParserK $ D.manyTill f (D.fromParserK p1) (D.fromParserK p2)