@@ -169,8 +169,8 @@ module Streamly.Internal.Data.Parser.ParserD.Type
169169 -- * Types
170170 Initial (..)
171171 , Step (..)
172− , mapStateStep
173172 , extractStep
173+ , bimapOverrideCount
174174 , Parser (..)
175175 , ParseError (..)
176176 , rmapM
@@ -180,8 +180,6 @@ module Streamly.Internal.Data.Parser.ParserD.Type
180180 , toParserK
181181
182182 -- * Constructors
183− , parser
184− , parserM
185183
186184 , fromPure
187185 , fromEffect
@@ -201,8 +199,8 @@ module Streamly.Internal.Data.Parser.ParserD.Type
201199 , lmapM
202200 , filter
203201
204− , noErrorUnsafeSplit_
205202 , noErrorUnsafeSplitWith
203+ , noErrorUnsafeSplit_
206204 , noErrorUnsafeConcatMap
207205 )
208206where
@@ -215,7 +213,6 @@ import Control.Monad (MonadPlus(..), (>=>))
215213import Control.Monad.IO.Class (MonadIO, liftIO)
216214import Control.Monad.Reader.Class (MonadReader, ask, local)
217215import Control.Monad.State.Class (MonadState, get, put)
218−import Control.Monad.Catch (MonadCatch, try, throwM, MonadThrow)
219216import Data.Bifunctor (Bifunctor(..))
220217import Fusion.Plugin.Types (Fuse(..))
221218import Streamly.Internal.Data.Fold.Type (Fold(..), toList)
@@ -230,6 +227,7 @@ import Prelude hiding (concatMap, filter)
230227-- >>> :m
231228-- >>> :set -package streamly
232229-- >>> import Control.Applicative ((<|>))
230+-- >>> import Data.Bifunctor (second)
233231-- >>> import Prelude hiding (concatMap)
234232-- >>> import qualified Streamly.Prelude as Stream
235233-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
@@ -269,21 +267,9 @@ instance Bifunctor Initial where
269267 bimap _ g (IDone b) = IDone (g b)
270268 bimap _ _ (IError err) = IError err
271269
272− {-# INLINE first #-}
273− first f (IPartial a) = IPartial (f a)
274− first _ (IDone x) = IDone x
275− first _ (IError err) = IError err
276−
277− {-# INLINE second #-}
278− second _ (IPartial x) = IPartial x
279− second f (IDone a) = IDone (f a)
280− second _ (IError err) = IError err
281−
282270-- | Maps a function over the result held by 'IDone'.
283271--
284−-- @
285−-- fmap = 'second'
286−-- @
272+-- >>> fmap = second
287273--
288274-- /Internal/
289275--
@@ -297,7 +283,7 @@ instance Functor (Initial s) where
297283-- Done Int (Either String b)
298284--
299285-- In this case Error may also have a "leftover" return. This means that after
300−-- serveral successful partial results the last segment parsing failed and we
286+-- several successful partial results the last segment parsing failed and we
301287-- are returning the leftover of that. The driver may choose to restart from
302288-- the last segment where this parser failed or from the beginning.
303289--
@@ -335,19 +321,20 @@ instance Functor (Initial s) where
335321{-# ANN type Step Fuse #-}
336322data Step s b =
337323 Partial !Int !s
338− -- ^ @Partial count state@. The following hold:
324+ -- ^ @Partial count state@. The following hold on Partial result:
339325 --
340326 -- 1. @extract@ on @state@ would succeed and give a result.
341− -- 2. Current input stream position is reset to @current position - count@.
342− -- 3. All input before the new current position is dropped. The parser can
327+ -- 2. Input stream position is reset to @current position - count@.
328+ -- 3. All input before the new position is dropped. The parser can
343329 -- never backtrack beyond this position.
344330
345331 | Continue !Int !s
346− -- ^ @Continue count state@. The following hold:
332+ -- ^ @Continue count state@. The following hold on a Continue result:
347333 --
348− -- 1. @extract@ on @state@ would give the last 'Partial' result or throw
349− -- 'ParseError' if there is none.
350− -- 2. Current input stream position is reset to @current position - count@.
334+ -- 1. If there was a 'Partial' result in past, @extract@ on @state@ would
335+ -- give that result as 'Done' otherwise it may return 'Error' or
336+ -- 'Continue'.
337+ -- 2. Input stream position is reset to @current position - count@.
351338 -- 3. the input is retained in a backtrack buffer.
352339
353340 | Done !Int !b
@@ -363,33 +350,50 @@ data Step s b =
363350 -- The parsing operation may backtrack to the beginning and try another
364351 -- alternative.
365352
353+-- | Map first function over the state and second over the result.
354+instance Bifunctor Step where
355+ {-# INLINE bimap #-}
356+ bimap f g step =
357+ case step of
358+ Partial n s -> Partial n (f s)
359+ Continue n s -> Continue n (f s)
360+ Done n b -> Done n (g b)
361+ Error err -> Error err
362+
363+-- | Bimap discarding the count, and using the supplied count instead.
364+bimapOverrideCount :: Int -> (s -> s1) -> (b -> b1) -> Step s b -> Step s1 b1
365+bimapOverrideCount n f g step =
366+ case step of
367+ Partial _ s -> Partial n (f s)
368+ Continue _ s -> Continue n (f s)
369+ Done _ b -> Done n (g b)
370+ Error err -> Error err
371+
372+-- | fmap = second
366373instance Functor (Step s) where
367374 {-# INLINE fmap #-}
368− fmap _ (Partial n s) = Partial n s
369− fmap _ (Continue n s) = Continue n s
370− fmap f (Done n b) = Done n (f b)
371− fmap _ (Error err) = Error err
375+ fmap = second
376+
377+{-# INLINE assertStepCount #-}
378+assertStepCount :: Int -> Step s b -> Step s b
379+assertStepCount i step =
380+ case step of
381+ Partial n _ -> assert (i == n) step
382+ Continue n _ -> assert (i == n) step
383+ Done n _ -> assert (i == n) step
384+ Error _ -> step
372385
373386-- | Map an extract function over the state of Step
374387--
375388{-# INLINE extractStep #-}
376−extractStep :: Monad m => (s -> m b) -> Step s b -> m (Step s1 b)
389+extractStep :: Monad m => (s -> m (Step s1 b)) -> Step s b -> m (Step s1 b)
377390extractStep f res =
378391 case res of
379− Partial n s1 -> Done n <$> f s1
392+ Partial n s1 -> assertStepCount n <$> f s1
380393 Done n b -> return $ Done n b
381− Continue n s1 -> Done n <$> f s1
394+ Continue n s1 -> assertStepCount n <$> f s1
382395 Error err -> return $ Error err
383396
384−{-# INLINE mapStateStep #-}
385−mapStateStep :: (s -> s1) -> Step s b -> Step s1 b
386−mapStateStep f res =
387− case res of
388− Partial n s1 -> Partial n $ f s1
389− Done n b -> Done n b
390− Continue n s1 -> Continue n $ f s1
391− Error err -> Error err
392−
393397-- | Map a monadic function over the result @b@ in @Step s b@.
394398--
395399-- /Internal/
@@ -415,13 +419,18 @@ mapMStep f res =
415419-- /Pre-release/
416420--
417421data Parser m a b =
418− forall s. Parser (s -> a -> m (Step s b)) (m (Initial s b)) (s -> m b)
419−
420−-- | This exception is used for two purposes:
421−--
422−-- * When a parser ultimately fails, the user of the parser is intimated via
423−-- this exception.
424−-- * When the "extract" function of a parser needs to throw an error.
422+ forall s. Parser
423+ (s -> a -> m (Step s b))
424+ -- Initial cannot return "Partial/Done n" or "Continue". Continue 0 is
425+ -- same as Partial 0. In other words it cannot backtrack.
426+ (m (Initial s b))
427+ -- Extract can only return Partial or Continue n. In other words it can
428+ -- only backtrack or return partial result/error. But we do not return
429+ -- result in Partial, therefore, we have to use Done instead of Partial.
430+ (s -> m (Step s b))
431+
432+-- | This exception is used when a parser ultimately fails, the user of the
433+-- parser is intimated via this exception.
425434--
426435-- /Pre-release/
427436--
@@ -434,13 +443,14 @@ instance Exception ParseError where
434443instance Functor m => Functor (Parser m a) where
435444 {-# INLINE fmap #-}
436445 fmap f (Parser step1 initial1 extract) =
437− Parser step initial (fmap2 f extract)
446+ Parser step initial (fmap3 f extract)
438447
439448 where
440449
441450 initial = fmap2 f initial1
442451 step s b = fmap2 f (step1 s b)
443452 fmap2 g = fmap (fmap g)
453+ fmap3 g = fmap2 (fmap g)
444454
445455-------------------------------------------------------------------------------
446456-- Convert direct style 'Parser' to CPS style 'K.Parser'
@@ -457,40 +467,52 @@ instance Functor m => Functor (Parser m a) where
457467--
458468{-# INLINE_NORMAL parseDToK #-}
459469parseDToK
460− :: MonadCatch m
470+ :: Monad m
461471 => (s -> a -> m (Step s b))
462472 -> m (Initial s b)
463− -> (s -> m b)
473+ -> (s -> m (Step s b))
464474 -> Int
465475 -> (Int, Int)
466476 -> ((Int, Int) -> K.Parse b -> m (K.Step m a r))
467477 -> m (K.Step m a r)
468478
479+-- Non 'Alternative' case.
469480parseDToK pstep initial extract leftover (0, _) cont = do
470481 res <- initial
471482 case res of
472483 IPartial r -> return $ K.Continue leftover (parseCont (return r))
473− IDone b -> cont (0,0) (K.Success 0 b)
474− IError err -> cont (0,0) (K.Failure err)
484+ IDone b -> cont state (K.Success 0 b)
485+ IError err -> cont state (K.Failure err)
475486
476487 where
477488
489+ -- The continuation is called with (0,0) state i.e. Alternative level
490+ -- is 0 and the used count is 0. Alternative level is 0 because the level
491+ -- passed in the argument above is 0, the "used" count is 0 because it is
492+ -- not useful when Alternative level is 0. We should probably use a Maybe
493+ -- type for the state but that might impact performance, need to measure.
494+ state = (0,0)
495+
478496 parseCont pst (Just x) = do
479497 r <- pst
480498 pRes <- pstep r x
481499 case pRes of
482− Done n b -> cont (0,0) (K.Success n b)
483− Error err -> cont (0,0) (K.Failure err)
500+ Done n b -> cont state (K.Success n b)
501+ Error err -> cont state (K.Failure err)
484502 Partial n pst1 -> return $ K.Partial n (parseCont (return pst1))
485503 Continue n pst1 -> return $ K.Continue n (parseCont (return pst1))
486504
487505 parseCont acc Nothing = do
488506 pst <- acc
489− r <- try $ extract pst
507+ r <- extract pst
490508 case r of
491− Left (e :: ParseError) -> cont (0,0) (K.Failure (displayException e))
492− Right b -> cont (0,0) (K.Success 0 b)
509+ Done n b -> cont state (K.Success n b)
510+ Error err -> cont state (K.Failure err)
511+ Partial _ _ -> error "Bug: parseDToK Partial unreachable"
512+ Continue n pst1 -> return $ K.Continue n (parseCont (return pst1))
493513
514+-- 'Alternative' case. Used count needs to be maintained when inside an
515+-- Alternative.
494516parseDToK pstep initial extract leftover (level, count) cont = do
495517 res <- initial
496518 case res of
@@ -518,18 +540,25 @@ parseDToK pstep initial extract leftover (level, count) cont = do
518540 return $ K.Continue n (parseCont (cnt1 - n) (return pst1))
519541 parseCont cnt acc Nothing = do
520542 pst <- acc
521− r <- try $ extract pst
543+ r <- extract pst
522544 let s = (level, cnt)
523545 case r of
524− Left (e :: ParseError) -> cont s (K.Failure (displayException e))
525− Right b -> cont s (K.Success 0 b)
546+ Done n b -> do
547+ assertM(n <= cnt)
548+ cont s (K.Success n b)
549+ Partial _ _ -> error "Bug: parseDToK Partial unreachable"
550+ Error e ->
551+ cont s (K.Failure e)
552+ Continue n pst1 -> do
553+ assertM(n <= cnt)
554+ return $ K.Continue n (parseCont (cnt - n) (return pst1))
526555
527556-- | Convert a direct style 'Parser' to a CPS style 'K.Parser'.
528557--
529558-- /Pre-release/
530559--
531560{-# INLINE_LATE toParserK #-}
532−toParserK :: MonadCatch m => Parser m a b -> K.Parser m a b
561+toParserK :: Monad m => Parser m a b -> K.Parser m a b
533562toParserK (Parser step initial extract) =
534563 K.MkParser $ parseDToK step initial extract
535564
@@ -549,14 +578,14 @@ parserDone _ (K.Failure e) = return $ K.Error e
549578--
550579-- /Pre-release/
551580--
552−extractParse :: MonadThrow m => (Maybe a -> m (K.Step m a b)) -> m b
581+extractParse :: Monad m => (Maybe a -> m (K.Step m a b)) -> m (Step s b)
553582extractParse cont = do
554583 r <- cont Nothing
555584 case r of
556− K.Done _ b -> return b
585+ K.Done n b -> return (Done n b)
557586 K.Partial _ _ -> error "Bug: extractParse got Partial"
558587 K.Continue _ cont1 -> extractParse cont1
559− K.Error e -> throwM $ ParseError e
588+ K.Error e -> return $ Error e
560589
561590data FromParserK b c = FPKDone !Int !b | FPKCont c
562591
@@ -568,13 +597,13 @@ data FromParserK b c = FPKDone !Int !b | FPKCont c
568597-- /Pre-release/
569598--
570599{-# INLINE_LATE fromParserK #-}
571−fromParserK :: MonadThrow m => K.Parser m a b -> Parser m a b
572−fromParserK parser0 = Parser step initial extract
600+fromParserK :: Monad m => K.Parser m a b -> Parser m a b
601+fromParserK parser = Parser step initial extract
573602
574603 where
575604
576605 initial = do
577− r <- K.runParser parser0 0 (0,0) parserDone
606+ r <- K.runParser parser 0 (0,0) parserDone
578607 return $ case r of
579608 K.Done n b -> IPartial $ FPKDone n b
580609 K.Error e -> IError e
@@ -596,7 +625,7 @@ fromParserK parser0 = Parser step initial extract
596625 K.Continue n cont1 -> Continue n (FPKCont cont1)
597626
598627 -- Note, we can only reach FPKDone and FPKError from "initial".
599− extract (FPKDone _ b) = return b
628+ extract (FPKDone n b) = return (Done n b)
600629 extract (FPKCont cont) = extractParse cont
601630
602631#ifndef DISABLE_FUSION
@@ -606,30 +635,6 @@ fromParserK parser0 = Parser step initial extract
606635 forall s. fromParserK (toParserK s) = s #-}
607636#endif
608637
609−------------------------------------------------------------------------------
610−-- General parser constructors
611−------------------------------------------------------------------------------
612−
613−-- | Make a parser using a parsing step and a starting value.
614−--
615−-- /Pre-release/
616−--
617−{-# INLINE parser #-}
618−parser :: Monad m => (b -> a -> Step b b) -> Initial b b -> Parser m a b
619−parser step initial =
620− Parser (\s a -> return $ step s a) (return initial) return
621−
622−-- | Like 'parser' but with a monadic step function.
623−--
624−-- >>> parserM step initial = ParserD.Parser step initial return
625−--
626−-- /Pre-release/
627−--
628−{-# INLINE parserM #-}
629−parserM ::
630− Monad m => (b -> a -> m (Step b b)) -> m (Initial b b) -> Parser m a b
631−parserM step initial = Parser step initial return
632−
633638------------------------------------------------------------------------------
634639-- Mapping on the output
635640------------------------------------------------------------------------------
@@ -639,12 +644,14 @@ parserM step initial = Parser step initial return
639644-- /Pre-release/
640645{-# INLINE rmapM #-}
641646rmapM :: Monad m => (b -> m c) -> Parser m a b -> Parser m a c
642−rmapM f (Parser step initial extract) = Parser step1 initial1 (extract >=> f)
647+rmapM f (Parser step initial extract) =
648+ Parser step1 initial1 (extract >=> mapMStep f)
643649
644650 where
645651
646652 initial1 = do
647653 res <- initial
654+ -- this is mapM f over result
648655 case res of
649656 IPartial x -> return $ IPartial x
650657 IDone a -> IDone <$> f a
@@ -686,7 +693,7 @@ data SeqParseState sl f sr = SeqParseL sl | SeqParseR f sr
686693-- /Pre-release/
687694--
688695{-# INLINE serialWith #-}
689−serialWith :: MonadThrow m
696+serialWith :: Monad m
690697 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
691698serialWith func (Parser stepL initialL extractL)
692699 (Parser stepR initialR extractR) =
@@ -695,11 +702,13 @@ serialWith func (Parser stepL initialL extractL)
695702 where
696703
697704 initial = do
705+ -- XXX We can use bimap here if we make this a Step type
698706 resL <- initialL
699707 case resL of
700708 IPartial sl -> return $ IPartial $ SeqParseL sl
701709 IDone bl -> do
702710 resR <- initialR
711+ -- XXX We can use bimap here if we make this a Step type
703712 return $ case resR of
704713 IPartial sr -> IPartial $ SeqParseR (func bl) sr
705714 IDone br -> IDone (func bl br)
@@ -712,6 +721,7 @@ serialWith func (Parser stepL initialL extractL)
712721 -- Important: Please do not use Applicative here. See
713722 -- https://github.com/composewell/streamly/issues/1033 and the problem
714723 -- defined in split_ for more info.
724+ -- XXX Use bimap
715725 resL <- stepL st a
716726 case resL of
717727 -- Note: We need to buffer the input for a possible Alternative
@@ -721,6 +731,8 @@ serialWith func (Parser stepL initialL extractL)
721731 Partial n s -> return $ Continue n (SeqParseL s)
722732 Continue n s -> return $ Continue n (SeqParseL s)
723733 Done n b -> do
734+ -- XXX Use bimap if we make this a Step type
735+ -- fmap (bimap (SeqParseR (func b)) (func b)) initialR
724736 initR <- initialR
725737 return $ case initR of
726738 IPartial sr -> Continue n $ SeqParseR (func b) sr
@@ -728,26 +740,41 @@ serialWith func (Parser stepL initialL extractL)
728740 IError err -> Error err
729741 Error err -> return $ Error err
730742
731− step (SeqParseR f st) a = do
732− resR <- stepR st a
733− return $ case resR of
734− Partial n s -> Partial n (SeqParseR f s)
735− Continue n s -> Continue n (SeqParseR f s)
736− Done n b -> Done n (f b)
737− Error err -> Error err
743+ step (SeqParseR f st) a = fmap (bimap (SeqParseR f) f) (stepR st a)
738744
739− extract (SeqParseR f sR) = fmap f (extractR sR)
745+ extract (SeqParseR f sR) = fmap (bimap (SeqParseR f) f) (extractR sR)
740746 extract (SeqParseL sL) = do
747+ -- XXX Use bimap here
741748 rL <- extractL sL
742− res <- initialR
743− case res of
744− IPartial sR -> do
745− rR <- extractR sR
746− return $ func rL rR
747− IDone rR -> return $ func rL rR
748− IError err -> throwM $ ParseError err
749+ case rL of
750+ Done n bL -> do
751+ -- XXX Use bimap here if we use Step type in Initial
752+ iR <- initialR
753+ case iR of
754+ IPartial sR -> do
755+ fmap
756+ (bimap (SeqParseR (func bL)) (func bL))
757+ (extractR sR)
758+ IDone bR -> return $ Done n $ func bL bR
759+ IError err -> return $ Error err
760+ Error err -> return $ Error err
761+ Partial _ _ -> error "Bug: serialWith extract 'Partial'"
762+ Continue n s -> return $ Continue n (SeqParseL s)
749763
750−-- | Works correctly only if the first parser is guaranteed to never fail.
764+-------------------------------------------------------------------------------
765+-- Sequential applicative for backtracking folds
766+-------------------------------------------------------------------------------
767+
768+-- XXX Create a newtype for nonfailing parsers and downgrade the parser to that
769+-- type before this operation and then upgrade.
770+--
771+-- We can do an inspection testing to reject unwanted constructors at compile
772+-- time.
773+--
774+-- We can use the compiler to automatically annotate accumulators, terminating
775+-- folds, non-failing parsers and failing parsers.
776+
777+-- | Works correctly only if both the parsers are guaranteed to never fail.
751778{-# INLINE noErrorUnsafeSplitWith #-}
752779noErrorUnsafeSplitWith :: Monad m
753780 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
@@ -757,24 +784,23 @@ noErrorUnsafeSplitWith func (Parser stepL initialL extractL)
757784
758785 where
759786
787+ errMsg e = error $ "noErrorUnsafeSplitWith: unreachable: " ++ e
788+
760789 initial = do
761790 resL <- initialL
762791 case resL of
763792 IPartial sl -> return $ IPartial $ SeqParseL sl
764793 IDone bl -> do
765794 resR <- initialR
766− return $ case resR of
767− IPartial sr -> IPartial $ SeqParseR (func bl) sr
768− IDone br -> IDone (func bl br)
769− IError err -> IError err
770− IError err -> return $ IError err
795+ return $ bimap (SeqParseR (func bl)) (func bl) resR
796+ IError err -> errMsg err
771797
772798 -- Note: For the composed parse to terminate, the left parser has to be
773799 -- a terminating parser returning a Done at some point.
774800 step (SeqParseL st) a = do
775801 r <- stepL st a
776802 case r of
777− -- Assume that the first parser can never fail, therefore we do not
803+ -- Assume that the parser can never fail, therefore, we do not
778804 -- need to keep the input for backtracking.
779805 Partial n s -> return $ Partial n (SeqParseL s)
780806 Continue n s -> return $ Continue n (SeqParseL s)
@@ -784,28 +810,29 @@ noErrorUnsafeSplitWith func (Parser stepL initialL extractL)
784810 $ case res of
785811 IPartial sr -> Partial n $ SeqParseR (func b) sr
786812 IDone br -> Done n (func b br)
787− IError err -> Error err
788− Error err -> return $ Error err
813+ IError err -> errMsg err
814+ Error err -> errMsg err
789815
790− step (SeqParseR f st) a = do
791− r <- stepR st a
792− return $ case r of
793− Partial n s -> Partial n (SeqParseR f s)
794− Continue n s -> Continue n (SeqParseR f s)
795− Done n b -> Done n (f b)
796− Error err -> Error err
816+ step (SeqParseR f st) a = fmap (bimap (SeqParseR f) f) (stepR st a)
817+
818+ extract (SeqParseR f sR) = fmap (bimap (SeqParseR f) f) (extractR sR)
797819
798− extract (SeqParseR f sR) = fmap f (extractR sR)
799820 extract (SeqParseL sL) = do
800821 rL <- extractL sL
801− res <- initialR
802− case res of
803− IPartial sR -> do
804− rR <- extractR sR
805− return $ func rL rR
806− IDone rR -> return $ func rL rR
807− IError err -> error $ "noErrorUnsafeSplitWith: cannot use a "
808− ++ "failing parser. Parser failed with: " ++ err
822+ case rL of
823+ Done n bL -> do
824+ iR <- initialR
825+ case iR of
826+ IPartial sR -> do
827+ rR <- extractR sR
828+ return
829+ $ bimapOverrideCount
830+ n (SeqParseR (func bL)) (func bL) rR
831+ IDone bR -> return $ Done n $ func bL bR
832+ IError err -> errMsg err
833+ Error err -> errMsg err
834+ Partial _ _ -> errMsg "Partial"
835+ Continue n s -> return $ Continue n (SeqParseL s)
809836
810837{-# ANN type SeqAState Fuse #-}
811838data SeqAState sl sr = SeqAL sl | SeqAR sr
@@ -816,7 +843,7 @@ data SeqAState sl sr = SeqAL sl | SeqAR sr
816843-- /Pre-release/
817844--
818845{-# INLINE split_ #-}
819−split_ :: MonadThrow m => Parser m x a -> Parser m x b -> Parser m x b
846+split_ :: Monad m => Parser m x a -> Parser m x b -> Parser m x b
820847split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
821848 Parser step initial extract
822849
@@ -828,10 +855,7 @@ split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
828855 IPartial sl -> return $ IPartial $ SeqAL sl
829856 IDone _ -> do
830857 resR <- initialR
831− return $ case resR of
832− IPartial sr -> IPartial $ SeqAR sr
833− IDone br -> IDone br
834− IError err -> IError err
858+ return $ first SeqAR resR
835859 IError err -> return $ IError err
836860
837861 -- Note: For the composed parse to terminate, the left parser has to be
@@ -853,40 +877,43 @@ split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
853877 IError err -> Error err
854878 Error err -> return $ Error err
855879
856− step (SeqAR st) a =
857− (\case
858− Partial n s -> Partial n (SeqAR s)
859− Continue n s -> Continue n (SeqAR s)
860− Done n b -> Done n b
861− Error err -> Error err) <$> stepR st a
880+ step (SeqAR st) a = first SeqAR <$> stepR st a
862881
863− extract (SeqAR sR) = extractR sR
882+ extract (SeqAR sR) = fmap (first SeqAR) (extractR sR)
864883 extract (SeqAL sL) = do
865− _ <- extractL sL
866− res <- initialR
867− case res of
868− IPartial sR -> extractR sR
869− IDone rR -> return rR
870− IError err -> throwM $ ParseError err
884+ rL <- extractL sL
885+ case rL of
886+ Done n _ -> do
887+ iR <- initialR
888+ -- XXX For initial we can have a bimap with leftover.
889+ case iR of
890+ IPartial sR ->
891+ fmap (bimapOverrideCount n SeqAR id) (extractR sR)
892+ IDone bR -> return $ Done n bR
893+ IError err -> return $ Error err
894+ Error err -> return $ Error err
895+ Partial _ _ -> error "split_: Partial"
896+ Continue n s -> return $ Continue n (SeqAL s)
871897
898+-- For backtracking folds
872899{-# INLINE noErrorUnsafeSplit_ #-}
873−noErrorUnsafeSplit_ :: MonadThrow m => Parser m x a -> Parser m x b -> Parser m x b
874−noErrorUnsafeSplit_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
900+noErrorUnsafeSplit_ :: Monad m => Parser m x a -> Parser m x b -> Parser m x b
901+noErrorUnsafeSplit_
902+ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
875903 Parser step initial extract
876904
877905 where
878906
907+ errMsg e = error $ "noErrorUnsafeSplit_: unreachable: " ++ e
908+
879909 initial = do
880910 resL <- initialL
881911 case resL of
882912 IPartial sl -> return $ IPartial $ SeqAL sl
883913 IDone _ -> do
884914 resR <- initialR
885− return $ case resR of
886− IPartial sr -> IPartial $ SeqAR sr
887− IDone br -> IDone br
888− IError err -> IError err
889− IError err -> return $ IError err
915+ return $ first SeqAR resR
916+ IError err -> errMsg err
890917
891918 -- Note: For the composed parse to terminate, the left parser has to be
892919 -- a terminating parser returning a Done at some point.
@@ -903,27 +930,28 @@ noErrorUnsafeSplit_ (Parser stepL initialL extractL) (Parser stepR initialR extr
903930 return $ case initR of
904931 IPartial s -> Partial n (SeqAR s)
905932 IDone b -> Done n b
906− IError err -> Error err
907− Error err -> return $ Error err
933+ IError err -> errMsg err
934+ Error err -> errMsg err
908935
909− step (SeqAR st) a =
910− (\case
911− Partial n s -> Partial n (SeqAR s)
912− Continue n s -> Continue n (SeqAR s)
913− Done n b -> Done n b
914− Error err -> Error err) <$> stepR st a
936+ step (SeqAR st) a = first SeqAR <$> stepR st a
915937
916− extract (SeqAR sR) = extractR sR
938+ extract (SeqAR sR) = fmap (first SeqAR) (extractR sR)
917939 extract (SeqAL sL) = do
918− _ <- extractL sL
919− res <- initialR
920− case res of
921− IPartial sR -> extractR sR
922− IDone rR -> return rR
923− IError err -> throwM $ ParseError err
940+ rL <- extractL sL
941+ case rL of
942+ Done n _ -> do
943+ iR <- initialR
944+ case iR of
945+ IPartial sR -> do
946+ fmap (bimapOverrideCount n SeqAR id) (extractR sR)
947+ IDone bR -> return $ Done n bR
948+ IError err -> errMsg err
949+ Error err -> errMsg err
950+ Partial _ _ -> error "split_: Partial"
951+ Continue n s -> return $ Continue n (SeqAL s)
924952
925953-- | 'Applicative' form of 'serialWith'.
926−instance MonadThrow m => Applicative (Parser m a) where
954+instance Monad m => Applicative (Parser m a) where
927955 {-# INLINE pure #-}
928956 pure = fromPure
929957
@@ -936,7 +964,6 @@ instance MonadThrow m => Applicative (Parser m a) where
936964 {-# INLINE liftA2 #-}
937965 liftA2 f x = (<*>) (fmap f x)
938966
939−
940967-------------------------------------------------------------------------------
941968-- Sequential Alternative
942969-------------------------------------------------------------------------------
@@ -948,9 +975,11 @@ data AltParseState sl sr = AltParseL Int sl | AltParseR sr
948975-- quadratic time complexity, because each composition adds a new branch that
949976-- each subsequent alternative's input element has to go through, therefore, it
950977-- cannot scale to a large number of compositions
951−--
978+
952979-- | See 'Streamly.Internal.Data.Parser.alt'.
953980--
981+-- /Time Complexity:/ O(n^2) where n is the number of compositions.
982+--
954983-- /Pre-release/
955984--
956985{-# INLINE alt #-}
@@ -1001,15 +1030,30 @@ alt (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
10011030 Done n b -> Done n b
10021031 Error err -> Error err
10031032
1004− extract (AltParseR sR) = extractR sR
1005− extract (AltParseL _ sL) = extractL sL
1033+ extract (AltParseR sR) = fmap (first AltParseR) (extractR sR)
1034+
1035+ extract (AltParseL cnt sL) = do
1036+ rL <- extractL sL
1037+ case rL of
1038+ Done n b -> return $ Done n b
1039+ Error _ -> do
1040+ res <- initialR
1041+ return
1042+ $ case res of
1043+ IPartial rR -> Continue cnt (AltParseR rR)
1044+ IDone b -> Done cnt b
1045+ IError err -> Error err
1046+ Partial _ _ -> error "Bug: serialWith extract 'Partial'"
1047+ Continue n s -> do
1048+ assertM(n == cnt)
1049+ return $ Continue n (AltParseL 0 s)
10061050
10071051-- | See documentation of 'Streamly.Internal.Data.Parser.many'.
10081052--
10091053-- /Pre-release/
10101054--
10111055{-# INLINE splitMany #-}
1012−splitMany :: MonadCatch m => Parser m a b -> Fold m b c -> Parser m a c
1056+splitMany :: Monad m => Parser m a b -> Fold m b c -> Parser m a c
10131057splitMany (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
10141058 Parser step initial extract
10151059
@@ -1051,17 +1095,21 @@ splitMany (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
10511095 xs <- fextract fs
10521096 return $ Done cnt1 xs
10531097
1054− extract (Tuple3' _ 0 fs) = fextract fs
1055− -- XXX The "try" may impact performance if this parser is used as a scan
1056− extract (Tuple3' s _ fs) = do
1057− r <- try $ extract1 s
1098+ extract (Tuple3' _ 0 fs) = fmap (Done 0) (fextract fs)
1099+ extract (Tuple3' s cnt fs) = do
1100+ r <- extract1 s
10581101 case r of
1059− Left (_ :: ParseError) -> fextract fs
1060− Right b -> do
1102+ Error _ -> fmap (Done cnt) (fextract fs)
1103+ Done n b -> do
1104+ assertM(n <= cnt)
10611105 fs1 <- fstep fs b
10621106 case fs1 of
1063− FL.Partial s1 -> fextract s1
1064− FL.Done b1 -> return b1
1107+ FL.Partial s1 -> fmap (Done n) (fextract s1)
1108+ FL.Done b1 -> return (Done n b1)
1109+ Partial _ _ -> error "splitMany: Partial in extract"
1110+ Continue n s1 -> do
1111+ assertM(n == cnt)
1112+ return (Continue n (Tuple3' s1 0 fs))
10651113
10661114-- | Like splitMany, but inner fold emits an output at the end even if no input
10671115-- is received.
@@ -1069,7 +1117,7 @@ splitMany (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
10691117-- /Internal/
10701118--
10711119{-# INLINE splitManyPost #-}
1072−splitManyPost :: MonadCatch m => Parser m a b -> Fold m b c -> Parser m a c
1120+splitManyPost :: Monad m => Parser m a b -> Fold m b c -> Parser m a c
10731121splitManyPost (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
10741122 Parser step initial extract
10751123
@@ -1111,23 +1159,27 @@ splitManyPost (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
11111159 xs <- fextract fs
11121160 return $ Done cnt1 xs
11131161
1114− -- XXX The "try" may impact performance if this parser is used as a scan
1115− extract (Tuple3' s _ fs) = do
1116− r <- try $ extract1 s
1162+ extract (Tuple3' s cnt fs) = do
1163+ r <- extract1 s
11171164 case r of
1118− Left (_ :: ParseError) -> fextract fs
1119− Right b -> do
1165+ Error _ -> fmap (Done cnt) (fextract fs)
1166+ Done n b -> do
1167+ assertM(n <= cnt)
11201168 fs1 <- fstep fs b
11211169 case fs1 of
1122− FL.Partial s1 -> fextract s1
1123− FL.Done b1 -> return b1
1170+ FL.Partial s1 -> fmap (Done n) (fextract s1)
1171+ FL.Done b1 -> return (Done n b1)
1172+ Partial _ _ -> error "splitMany: Partial in extract"
1173+ Continue n s1 -> do
1174+ assertM(n == cnt)
1175+ return (Continue n (Tuple3' s1 0 fs))
11241176
11251177-- | See documentation of 'Streamly.Internal.Data.Parser.some'.
11261178--
11271179-- /Pre-release/
11281180--
11291181{-# INLINE splitSome #-}
1130−splitSome :: MonadCatch m => Parser m a b -> Fold m b c -> Parser m a c
1182+splitSome :: Monad m => Parser m a b -> Fold m b c -> Parser m a c
11311183splitSome (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
11321184 Parser step initial extract
11331185
@@ -1196,29 +1248,41 @@ splitSome (Parser step1 initial1 extract1) (Fold fstep finitial fextract) =
11961248 fstep fs b >>= handleCollect (Partial n) (Done n)
11971249 Error _ -> Done cnt1 <$> fextract fs
11981250
1199− -- XXX The "try" may impact performance if this parser is used as a scan
1200− extract (Tuple3' s _ (Left fs)) = do
1201− b <- extract1 s
1202− fs1 <- fstep fs b
1203− case fs1 of
1204− FL.Partial s1 -> fextract s1
1205− FL.Done b1 -> return b1
1206− extract (Tuple3' s _ (Right fs)) = do
1207− r <- try $ extract1 s
1251+ extract (Tuple3' s cnt (Left fs)) = do
1252+ r <- extract1 s
12081253 case r of
1209− Left (_ :: ParseError) -> fextract fs
1210− Right b -> do
1254+ Error err -> return (Error err)
1255+ Done n b -> do
1256+ assertM(n <= cnt)
12111257 fs1 <- fstep fs b
12121258 case fs1 of
1213− FL.Partial s1 -> fextract s1
1214− FL.Done b1 -> return b1
1259+ FL.Partial s1 -> fmap (Done n) (fextract s1)
1260+ FL.Done b1 -> return (Done n b1)
1261+ Partial _ _ -> error "splitSome: Partial in extract"
1262+ Continue n s1 -> do
1263+ assertM(n == cnt)
1264+ return (Continue n (Tuple3' s1 0 (Left fs)))
1265+ extract (Tuple3' s cnt (Right fs)) = do
1266+ r <- extract1 s
1267+ case r of
1268+ Error _ -> fmap (Done cnt) (fextract fs)
1269+ Done n b -> do
1270+ assertM(n <= cnt)
1271+ fs1 <- fstep fs b
1272+ case fs1 of
1273+ FL.Partial s1 -> fmap (Done n) (fextract s1)
1274+ FL.Done b1 -> return (Done n b1)
1275+ Partial _ _ -> error "splitSome: Partial in extract"
1276+ Continue n s1 -> do
1277+ assertM(n == cnt)
1278+ return (Continue n (Tuple3' s1 0 (Right fs)))
12151279
12161280-- | See 'Streamly.Internal.Data.Parser.die'.
12171281--
12181282-- /Pre-release/
12191283--
12201284{-# INLINE_NORMAL die #-}
1221−die :: MonadThrow m => String -> Parser m a b
1285+die :: Monad m => String -> Parser m a b
12221286die err = Parser undefined (pure (IError err)) undefined
12231287
12241288-- | See 'Streamly.Internal.Data.Parser.dieM'.
@@ -1226,7 +1290,7 @@ die err = Parser undefined (pure (IError err)) undefined
12261290-- /Pre-release/
12271291--
12281292{-# INLINE dieM #-}
1229−dieM :: MonadThrow m => m String -> Parser m a b
1293+dieM :: Monad m => m String -> Parser m a b
12301294dieM err = Parser undefined (IError <$> err) undefined
12311295
12321296-- Note: The default implementations of "some" and "many" loop infinitely
@@ -1245,7 +1309,7 @@ dieM err = Parser undefined (IError <$> err) undefined
12451309-- >>> Stream.parse (Parser.satisfy (> 0) <|> undefined) $ Stream.fromList [1..10]
12461310-- 1
12471311--
1248−instance MonadCatch m => Alternative (Parser m a) where
1312+instance Monad m => Alternative (Parser m a) where
12491313 {-# INLINE empty #-}
12501314 empty = die "empty"
12511315
@@ -1261,14 +1325,14 @@ instance MonadCatch m => Alternative (Parser m a) where
12611325{-# ANN type ConcatParseState Fuse #-}
12621326data ConcatParseState sl m a b =
12631327 ConcatParseL sl
1264− | forall s. ConcatParseR (s -> a -> m (Step s b)) s (s -> m b)
1328+ | forall s. ConcatParseR (s -> a -> m (Step s b)) s (s -> m (Step s b))
12651329
12661330-- | See 'Streamly.Internal.Data.Parser.concatMap'.
12671331--
12681332-- /Pre-release/
12691333--
12701334{-# INLINE concatMap #-}
1271−concatMap :: MonadThrow m =>
1335+concatMap :: Monad m =>
12721336 (b -> Parser m a c) -> Parser m a b -> Parser m a c
12731337concatMap func (Parser stepL initialL extractL) = Parser step initial extract
12741338
@@ -1314,18 +1378,28 @@ concatMap func (Parser stepL initialL extractL) = Parser step initial extract
13141378 Error err -> Error err
13151379
13161380 {-# INLINE extractP #-}
1317− extractP (Parser _ initialR extractR) = do
1381+ extractP n (Parser stepR initialR extractR) = do
13181382 res <- initialR
13191383 case res of
1320− IPartial s -> extractR s
1321− IDone b -> return b
1322− IError err -> throwM $ ParseError err
1323−
1324− extract (ConcatParseR _ s extractR) = extractR s
1325− extract (ConcatParseL sL) = extractL sL >>= extractP . func
1384+ IPartial s ->
1385+ fmap
1386+ (first (\s1 -> ConcatParseR stepR s1 extractR))
1387+ (extractR s)
1388+ IDone b -> return (Done n b)
1389+ IError err -> return $ Error err
1390+
1391+ extract (ConcatParseR stepR s extractR) =
1392+ fmap (first (\s1 -> ConcatParseR stepR s1 extractR)) (extractR s)
1393+ extract (ConcatParseL sL) = do
1394+ rL <- extractL sL
1395+ case rL of
1396+ Error err -> return $ Error err
1397+ Done n b -> extractP n $ func b
1398+ Partial _ _ -> error "concatMap: extract Partial"
1399+ Continue n s -> return $ Continue n (ConcatParseL s)
13261400
13271401{-# INLINE noErrorUnsafeConcatMap #-}
1328−noErrorUnsafeConcatMap :: MonadThrow m =>
1402+noErrorUnsafeConcatMap :: Monad m =>
13291403 (b -> Parser m a c) -> Parser m a b -> Parser m a c
13301404noErrorUnsafeConcatMap func (Parser stepL initialL extractL) =
13311405 Parser step initial extract
@@ -1372,15 +1446,25 @@ noErrorUnsafeConcatMap func (Parser stepL initialL extractL) =
13721446 Error err -> Error err
13731447
13741448 {-# INLINE extractP #-}
1375− extractP (Parser _ initialR extractR) = do
1449+ extractP n (Parser stepR initialR extractR) = do
13761450 res <- initialR
13771451 case res of
1378− IPartial s -> extractR s
1379− IDone b -> return b
1380− IError err -> throwM $ ParseError err
1381−
1382− extract (ConcatParseR _ s extractR) = extractR s
1383− extract (ConcatParseL sL) = extractL sL >>= extractP . func
1452+ IPartial s ->
1453+ fmap
1454+ (first (\s1 -> ConcatParseR stepR s1 extractR))
1455+ (extractR s)
1456+ IDone b -> return (Done n b)
1457+ IError err -> return $ Error err
1458+
1459+ extract (ConcatParseR stepR s extractR) =
1460+ fmap (first (\s1 -> ConcatParseR stepR s1 extractR)) (extractR s)
1461+ extract (ConcatParseL sL) = do
1462+ rL <- extractL sL
1463+ case rL of
1464+ Error err -> return $ Error err
1465+ Done n b -> extractP n $ func b
1466+ Partial _ _ -> error "concatMap: extract Partial"
1467+ Continue n s -> return $ Continue n (ConcatParseL s)
13841468
13851469-- Note: The monad instance has quadratic performance complexity. It works fine
13861470-- for small number of compositions but for a scalable implementation we need a
@@ -1388,7 +1472,7 @@ noErrorUnsafeConcatMap func (Parser stepL initialL extractL) =
13881472
13891473-- | See documentation of 'Streamly.Internal.Data.Parser.ParserK.Type.Parser'.
13901474--
1391−instance MonadThrow m => Monad (Parser m a) where
1475+instance Monad m => Monad (Parser m a) where
13921476 {-# INLINE return #-}
13931477 return = pure
13941478
@@ -1400,14 +1484,14 @@ instance MonadThrow m => Monad (Parser m a) where
14001484
14011485-- | See documentation of 'Streamly.Internal.Data.Parser.ParserK.Type.Parser'.
14021486--
1403−instance MonadCatch m => MonadPlus (Parser m a) where
1487+instance Monad m => MonadPlus (Parser m a) where
14041488 {-# INLINE mzero #-}
14051489 mzero = die "mzero"
14061490
14071491 {-# INLINE mplus #-}
14081492 mplus = alt
14091493
1410−instance (MonadThrow m, MonadReader r m, MonadCatch m) => MonadReader r (Parser m a) where
1494+instance (Monad m, MonadReader r m) => MonadReader r (Parser m a) where
14111495 {-# INLINE ask #-}
14121496 ask = fromEffect ask
14131497
@@ -1417,14 +1501,14 @@ instance (MonadThrow m, MonadReader r m, MonadCatch m) => MonadReader r (Parser
14171501 (local f init')
14181502 (local f . extract)
14191503
1420−instance (MonadThrow m, MonadState s m) => MonadState s (Parser m a) where
1504+instance (Monad m, MonadState s m) => MonadState s (Parser m a) where
14211505 {-# INLINE get #-}
14221506 get = fromEffect get
14231507
14241508 {-# INLINE put #-}
14251509 put = fromEffect . put
14261510
1427−instance (MonadThrow m, MonadIO m) => MonadIO (Parser m a) where
1511+instance (Monad m, MonadIO m) => MonadIO (Parser m a) where
14281512 {-# INLINE liftIO #-}
14291513 liftIO = fromEffect . liftIO
14301514