@@ -36,9 +36,9 @@
36-- 'Step' functor provides the following commands to the fold driver
36-- 'Step' functor provides the following commands to the fold driver
37-- corresponding to the use cases outlined in the previous para:
37-- corresponding to the use cases outlined in the previous para:
39−-- 1. 'Continue': buffer the current input and go back to a previous
39+-- 1. 'Continue': buffer the current input and optionally go back to a previous
40-- position in the stream
40-- position in the stream
41−-- 2. 'Partial': buffer the current input and go back to a previous
41+-- 2. 'Partial': buffer the current input and optionally go back to a previous
42-- position in the stream, drop the buffer before that position.
42-- position in the stream, drop the buffer before that position.
43-- 3. 'Done': parser succeeded, returns how much input was leftover
43-- 3. 'Done': parser succeeded, returns how much input was leftover
44-- 4. 'Error': indicates that the parser has failed without a result
44-- 4. 'Error': indicates that the parser has failed without a result
@@ -111,7 +111,8 @@
112module Streamly.Internal.Data.Parser.ParserD.Types
112module Streamly.Internal.Data.Parser.ParserD.Types
114− Step (..)
115+ , Step (..)
115 , Parser (..)
116 , Parser (..)
116 , ParseError (..)
117 , ParseError (..)
@@ -135,6 +136,7 @@ import Control.Applicative (Alternative(..))
135import Control.Exception (assert, Exception(..))
136import Control.Exception (assert, Exception(..))
136import Control.Monad (MonadPlus(..))
137import Control.Monad (MonadPlus(..))
137import Control.Monad.Catch (MonadCatch, try, throwM, MonadThrow)
138import Control.Monad.Catch (MonadCatch, try, throwM, MonadThrow)
139+import Data.Bifunctor (Bifunctor(..))
138import Fusion.Plugin.Types (Fuse(..))
140import Fusion.Plugin.Types (Fuse(..))
139import Streamly.Internal.Data.Fold.Types (Fold(..), toList)
141import Streamly.Internal.Data.Fold.Types (Fold(..), toList)
140import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
142import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
@@ -151,6 +153,48 @@ import Prelude hiding (concatMap)
151-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
153-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
152-- >>> import qualified Streamly.Internal.Data.Parser as Parser
154-- >>> import qualified Streamly.Internal.Data.Parser as Parser
156+-- | The type of a 'Parser''s initial action.
160+{-# ANN type Initial Fuse #-}
162+ = IPartial !s -- ^ Wait for step function to be called with state @s@.
163+ | IDone !b -- ^ Return a result right away without an input.
164+ | IError String -- ^ Return an error right away without an input.
166+-- | @first@ maps on 'IPartial' and @second@ maps on 'IDone'.
170+instance Bifunctor Initial where
171+ {-# INLINE bimap #-}
172+ bimap f _ (IPartial a) = IPartial (f a)
173+ bimap _ g (IDone b) = IDone (g b)
174+ bimap _ _ (IError err) = IError err
176+ {-# INLINE first #-}
177+ first f (IPartial a) = IPartial (f a)
178+ first _ (IDone x) = IDone x
179+ first _ (IError err) = IError err
181+ {-# INLINE second #-}
182+ second _ (IPartial x) = IPartial x
183+ second f (IDone a) = IDone (f a)
184+ second _ (IError err) = IError err
186+-- | Maps a function over the result held by 'IDone'.
194+instance Functor (Initial s) where
154-- | The return type of a 'Parser' step.
198-- | The return type of a 'Parser' step.
156-- The parse operation feeds the input stream to the parser one element at a
200-- The parse operation feeds the input stream to the parser one element at a
@@ -231,7 +275,7 @@ instance Functor (Step s) where
231-- /Internal/
275-- /Internal/
233data Parser m a b =
277data Parser m a b =
234− forall s. Parser (s -> a -> m (Step s b)) (m s) (s -> m b)
278+ forall s. Parser (s -> a -> m (Step s b)) (m (Initial s b)) (s -> m b)
236-- | This exception is used for two purposes:
280-- | This exception is used for two purposes:
@@ -249,11 +293,12 @@ instance Exception ParseError where
250instance Functor m => Functor (Parser m a) where
294instance Functor m => Functor (Parser m a) where
251 {-# INLINE fmap #-}
295 {-# INLINE fmap #-}
252− fmap f (Parser step1 initial extract) =
296+ fmap f (Parser step1 initial1 extract) =
253 Parser step initial (fmap2 f extract)
297 Parser step initial (fmap2 f extract)
301+ initial = fmap2 f initial1
257 step s b = fmap2 f (step1 s b)
302 step s b = fmap2 f (step1 s b)
258 fmap2 g = fmap (fmap g)
303 fmap2 g = fmap (fmap g)
@@ -263,9 +308,7 @@ instance Functor m => Functor (Parser m a) where
264{-# INLINE_NORMAL yield #-}
309{-# INLINE_NORMAL yield #-}
265yield :: Monad m => b -> Parser m a b
310yield :: Monad m => b -> Parser m a b
266−yield b = Parser (\_ _ -> pure $ Done 1 b) -- step
311+yield b = Parser undefined (pure $ IDone b) undefined
267− (pure ()) -- initial
268− (\_ -> pure b) -- extract
270-- | See 'Streamly.Internal.Data.Parser.yieldM'.
313-- | See 'Streamly.Internal.Data.Parser.yieldM'.
@@ -273,9 +316,7 @@ yield b = Parser (\_ _ -> pure $ Done 1 b) -- step
274{-# INLINE yieldM #-}
317{-# INLINE yieldM #-}
275yieldM :: Monad m => m b -> Parser m a b
318yieldM :: Monad m => m b -> Parser m a b
276−yieldM b = Parser (\_ _ -> Done 1 <$> b) -- step
319+yieldM b = Parser undefined (IDone <$> b) undefined
277− (pure ()) -- initial
278− (const b) -- extract
280-------------------------------------------------------------------------------
321-------------------------------------------------------------------------------
281-- Sequential applicative
322-- Sequential applicative
@@ -296,7 +337,7 @@ data SeqParseState sl f sr = SeqParseL sl | SeqParseR f sr
296-- /Internal/
337-- /Internal/
298{-# INLINE splitWith #-}
339{-# INLINE splitWith #-}
299−splitWith :: Monad m
340+splitWith :: MonadThrow m
300 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
341 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
301splitWith func (Parser stepL initialL extractL)
342splitWith func (Parser stepL initialL extractL)
302 (Parser stepR initialR extractR) =
343 (Parser stepR initialR extractR) =
@@ -304,38 +345,55 @@ splitWith func (Parser stepL initialL extractL)
307− initial = SeqParseL <$> initialL
349+ resL <- initialL
351+ IPartial sl -> return $ IPartial $ SeqParseL sl
354+ return $ case resR of
355+ IPartial sr -> IPartial $ SeqParseR (func bl) sr
356+ IDone br -> IDone (func bl br)
357+ IError err -> IError err
358+ IError err -> return $ IError err
309 -- Note: For the composed parse to terminate, the left parser has to be
360 -- Note: For the composed parse to terminate, the left parser has to be
310 -- a terminating parser returning a Done at some point.
361 -- a terminating parser returning a Done at some point.
311− step (SeqParseL st) a = do
362+ step (SeqParseL st) a =
312− r <- stepL st a
363+ (\resL initR ->
313− case r of
364+ case resL of
314 -- Note: We need to buffer the input for a possible Alternative
365 -- Note: We need to buffer the input for a possible Alternative
315 -- e.g. in ((,) <$> p1 <*> p2) <|> p3, if p2 fails we have to
366 -- e.g. in ((,) <$> p1 <*> p2) <|> p3, if p2 fails we have to
316 -- backtrack and start running p3. So we need to keep the input
367 -- backtrack and start running p3. So we need to keep the input
317 -- buffered until we know that the applicative cannot fail.
368 -- buffered until we know that the applicative cannot fail.
318− Partial n s -> return $ Continue n (SeqParseL s)
369+ Partial n s -> Continue n (SeqParseL s)
319− Continue n s -> return $ Continue n (SeqParseL s)
370+ Continue n s -> Continue n (SeqParseL s)
320− Done n b -> Continue n <$> (SeqParseR (func b) <$> initialR)
373+ IPartial sr -> Continue n $ SeqParseR (func b) sr
321− Error err -> return $ Error err
374+ IDone br -> Done n (func b br)
375+ IError err -> Error err
376+ Error err -> Error err) <$> stepL st a <*> initialR
323− step (SeqParseR f st) a = do
378+ step (SeqParseR f st) a =
325− return $ case r of
379+ (\case
326 Partial n s -> Partial n (SeqParseR f s)
380 Partial n s -> Partial n (SeqParseR f s)
327 Continue n s -> Continue n (SeqParseR f s)
381 Continue n s -> Continue n (SeqParseR f s)
328 Done n b -> Done n (f b)
382 Done n b -> Done n (f b)
329− Error err -> Error err
383+ Error err -> Error err) <$> stepR st a
331 extract (SeqParseR f sR) = fmap f (extractR sR)
385 extract (SeqParseR f sR) = fmap f (extractR sR)
332 extract (SeqParseL sL) = do
386 extract (SeqParseL sL) = do
333 rL <- extractL sL
387 rL <- extractL sL
334− sR <- initialR
388+ res <- initialR
335− rR <- extractR sR
391+ rR <- extractR sR
336− return $ func rL rR
393+ IDone rR -> return $ func rL rR
337−
394+ IError err -> throwM $ ParseError err
338−-- Only use this if you know what you're doing
395+
396+-- | Works correctly only if the first parser is guaranteed to never fail.
339{-# INLINE noErrorUnsafeSplitWith #-}
397{-# INLINE noErrorUnsafeSplitWith #-}
340noErrorUnsafeSplitWith :: Monad m
398noErrorUnsafeSplitWith :: Monad m
341 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
399 => (a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
@@ -345,14 +403,34 @@ noErrorUnsafeSplitWith func (Parser stepL initialL extractL)
348− initial = SeqParseL <$> initialL
407+ resL <- initialL
409+ IPartial sl -> return $ IPartial $ SeqParseL sl
412+ return $ case resR of
413+ IPartial sr -> IPartial $ SeqParseR (func bl) sr
414+ IDone br -> IDone (func bl br)
415+ IError err -> IError err
416+ IError err -> return $ IError err
418+ -- Note: For the composed parse to terminate, the left parser has to be
419+ -- a terminating parser returning a Done at some point.
350 step (SeqParseL st) a = do
420 step (SeqParseL st) a = do
351 r <- stepL st a
421 r <- stepL st a
352 case r of
422 case r of
423+ -- Assume that the first parser can never fail, therefore we do not
424+ -- need to keep the input for backtracking.
353 Partial n s -> return $ Partial n (SeqParseL s)
425 Partial n s -> return $ Partial n (SeqParseL s)
354 Continue n s -> return $ Partial n (SeqParseL s)
426 Continue n s -> return $ Partial n (SeqParseL s)
355− Done n b -> Partial n <$> (SeqParseR (func b) <$> initialR)
431+ IPartial sr -> Partial n $ SeqParseR (func b) sr
432+ IDone br -> Done n (func b br)
433+ IError err -> Error err
356 Error err -> return $ Error err
434 Error err -> return $ Error err
358 step (SeqParseR f st) a = do
436 step (SeqParseR f st) a = do
@@ -366,9 +444,15 @@ noErrorUnsafeSplitWith func (Parser stepL initialL extractL)
366 extract (SeqParseR f sR) = fmap f (extractR sR)
444 extract (SeqParseR f sR) = fmap f (extractR sR)
367 extract (SeqParseL sL) = do
445 extract (SeqParseL sL) = do
368 rL <- extractL sL
446 rL <- extractL sL
369− sR <- initialR
447+ res <- initialR
370− rR <- extractR sR
450+ rR <- extractR sR
371− return $ func rL rR
451+ return $ func rL rR
452+ IDone rR -> return $ func rL rR
453+ IError err -> error $ "noErrorUnsafeSplitWith: cannot use a "
454+ ++ "failing parser. Parser failed with: " ++ err
373{-# ANN type SeqAState Fuse #-}
457{-# ANN type SeqAState Fuse #-}
374data SeqAState sl sr = SeqAL sl | SeqAR sr
458data SeqAState sl sr = SeqAL sl | SeqAR sr
@@ -379,23 +463,37 @@ data SeqAState sl sr = SeqAL sl | SeqAR sr
379-- /Internal/
463-- /Internal/
381{-# INLINE split_ #-}
465{-# INLINE split_ #-}
382−split_ :: Monad m => Parser m x a -> Parser m x b -> Parser m x b
466+split_ :: MonadThrow m => Parser m x a -> Parser m x b -> Parser m x b
383split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
467split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
384 Parser step initial extract
468 Parser step initial extract
388− initial = SeqAL <$> initialL
472+ initial = do
475+ IPartial sl -> return $ IPartial $ SeqAL sl
478+ return $ case resR of
479+ IPartial sr -> IPartial $ SeqAR sr
480+ IDone br -> IDone br
481+ IError err -> IError err
482+ IError err -> return $ IError err
390 -- Note: For the composed parse to terminate, the left parser has to be
484 -- Note: For the composed parse to terminate, the left parser has to be
391 -- a terminating parser returning a Done at some point.
485 -- a terminating parser returning a Done at some point.
392 step (SeqAL st) a =
486 step (SeqAL st) a =
393− (\r i -> case r of
487+ (\resL initR -> case resL of
394 -- Note: this leads to buffering even if we are not in an
488 -- Note: this leads to buffering even if we are not in an
395 -- Alternative composition.
489 -- Alternative composition.
396 Partial n s -> Continue n (SeqAL s)
490 Partial n s -> Continue n (SeqAL s)
397 Continue n s -> Continue n (SeqAL s)
491 Continue n s -> Continue n (SeqAL s)
398− Done n _ -> Continue n (SeqAR i)
494+ IPartial s -> Continue n (SeqAR s)
496+ IError err -> Error err
399 -- XXX should we sequence initialR monadically?
497 -- XXX should we sequence initialR monadically?
400 Error err -> Error err) <$> stepL st a <*> initialR
498 Error err -> Error err) <$> stepL st a <*> initialR
@@ -409,10 +507,14 @@ split_ (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
409 extract (SeqAR sR) = extractR sR
507 extract (SeqAR sR) = extractR sR
410 extract (SeqAL sL) = do
508 extract (SeqAL sL) = do
411 _ <- extractL sL
509 _ <- extractL sL
412− initialR >>= extractR
510+ res <- initialR
512+ IPartial sR -> extractR sR
513+ IDone rR -> return rR
514+ IError err -> throwM $ ParseError err
414-- | 'Applicative' form of 'splitWith'.
516-- | 'Applicative' form of 'splitWith'.
415−instance Monad m => Applicative (Parser m a) where
517+instance MonadThrow m => Applicative (Parser m a) where
416 {-# INLINE pure #-}
518 {-# INLINE pure #-}
417 pure = yield
519 pure = yield
@@ -445,7 +547,17 @@ alt (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
448− initial = AltParseL 0 <$> initialL
550+ initial = do
553+ IPartial sl -> return $ IPartial $ AltParseL 0 sl
554+ IDone bl -> return $ IDone bl
557+ return $ case resR of
558+ IPartial sr -> IPartial $ AltParseR sr
559+ IDone br -> IDone br
560+ IError err -> IError err
450 -- Once a parser yields at least one value it cannot fail. This
562 -- Once a parser yields at least one value it cannot fail. This
451 -- restriction helps us make backtracking more efficient, as we do not need
563 -- restriction helps us make backtracking more efficient, as we do not need
@@ -461,8 +573,12 @@ alt (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
461 return $ Continue n (AltParseL (cnt + 1 - n) s)
573 return $ Continue n (AltParseL (cnt + 1 - n) s)
462 Done n b -> return $ Done n b
574 Done n b -> return $ Done n b
463 Error _ -> do
575 Error _ -> do
464− rR <- initialR
576+ res <- initialR
465− return $ Continue (cnt + 1) (AltParseR rR)
579+ IPartial rR -> Continue (cnt + 1) (AltParseR rR)
580+ IDone b -> Done (cnt + 1) b
581+ IError err -> Error err
467 step (AltParseR st) a = do
583 step (AltParseR st) a = do
468 r <- stepR st a
584 r <- stepR st a
@@ -486,14 +602,25 @@ splitMany (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
489− initial = do
605+ -- Caution! There is mutual recursion here, inlining the right functions is
608+ {-# INLINE handleCollect #-}
609+ handleCollect partial done fres =
490− ps <- initial1 -- parse state
612+ pres <- initial1
491− res <- finitial -- fold state
613+ case pres of
492− return
614+ IPartial ps -> return $ partial $ Tuple3' ps 0 fs
493− $ case res of
615+ IDone pb ->
494− FL.Partial fs -> Tuple3' ps (0 :: Int) fs
616+ runCollectorWith (handleCollect partial done) fs pb
495− FL.Done _ ->
617+ IError _ -> done <$> fextract fs
496− error "splitMany: Done in initial not implemented"
618+ FL.Done fb -> return $ done fb
620+ -- Do not inline this
621+ runCollectorWith cont fs pb = fstep fs pb >>= cont
623+ initial = finitial >>= handleCollect IPartial IDone
498 {-# INLINE step #-}
625 {-# INLINE step #-}
499 step (Tuple3' st cnt fs) a = do
626 step (Tuple3' st cnt fs) a = do
@@ -507,13 +634,8 @@ splitMany (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
507 assert (cnt1 - n >= 0) (return ())
634 assert (cnt1 - n >= 0) (return ())
508 return $ Continue n (Tuple3' s (cnt1 - n) fs)
635 return $ Continue n (Tuple3' s (cnt1 - n) fs)
509 Done n b -> do
636 Done n b -> do
512 assert (cnt1 - n >= 0) (return ())
637 assert (cnt1 - n >= 0) (return ())
513− return
638+ fstep fs b >>= handleCollect (Partial n) (Done n)
515− FL.Partial s1 -> Partial n (Tuple3' s 0 s1)
516− FL.Done b1 -> Done n b1
517 Error _ -> do
639 Error _ -> do
518 xs <- fextract fs
640 xs <- fextract fs
519 return $ Done cnt1 xs
641 return $ Done cnt1 xs
@@ -540,14 +662,39 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
665+ -- Caution! There is mutual recursion here, inlining the right functions is
668+ {-# INLINE handleCollect #-}
669+ handleCollect partial done fres =
674+ IPartial ps -> return $ partial $ Tuple3' ps 0 $ Right fs
676+ runCollectorWith (handleCollect partial done) fs pb
677+ IError _ -> done <$> fextract fs
678+ FL.Done fb -> return $ done fb
680+ -- Do not inline this
681+ runCollectorWith cont fs pb = fstep fs pb >>= cont
543 initial = do
683 initial = do
544− ps <- initial1 -- parse state
545− res <- finitial -- fold state
684+ fres <- finitial
547− $ case res of
685+ case fres of
548− FL.Partial fs -> Tuple3' ps (0 :: Int) (Left fs)
686+ FL.Partial fs -> do
689+ IPartial ps -> return $ IPartial $ Tuple3' ps 0 $ Left fs
691+ runCollectorWith (handleCollect IPartial IDone) fs pb
692+ IError err -> return $ IError err
549− FL.Done _ ->
693+ FL.Done _ ->
550− error "splitSome: Done/Error in initial not implemented"
694+ return
696+ $ "splitSome: The collecting fold terminated without"
697+ ++ " consuming any elements."
552 {-# INLINE step #-}
699 {-# INLINE step #-}
553 step (Tuple3' st cnt (Left fs)) a = do
700 step (Tuple3' st cnt (Left fs)) a = do
@@ -563,12 +710,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
563 return $ Continue n (Tuple3' s (cnt1 - n) (Left fs))
710 return $ Continue n (Tuple3' s (cnt1 - n) (Left fs))
564 Done n b -> do
711 Done n b -> do
565 assert (cnt1 - n >= 0) (return ())
712 assert (cnt1 - n >= 0) (return ())
566− s <- initial1
713+ fstep fs b >>= handleCollect (Partial n) (Done n)
570− FL.Partial s1 -> Partial n (Tuple3' s 0 (Right s1))
571− FL.Done b1 -> Done n b1
572 Error err -> return $ Error err
714 Error err -> return $ Error err
573 step (Tuple3' st cnt (Right fs)) a = do
715 step (Tuple3' st cnt (Right fs)) a = do
574 r <- step1 st a
716 r <- step1 st a
@@ -582,12 +724,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
582 return $ Continue n (Tuple3' s (cnt1 - n) (Right fs))
724 return $ Continue n (Tuple3' s (cnt1 - n) (Right fs))
583 Done n b -> do
725 Done n b -> do
584 assert (cnt1 - n >= 0) (return ())
726 assert (cnt1 - n >= 0) (return ())
585− s <- initial1
727+ fstep fs b >>= handleCollect (Partial n) (Done n)
589− FL.Partial s1 -> Partial n (Tuple3' s 0 (Right s1))
590− FL.Done b1 -> Done n b1
591 Error _ -> Done cnt1 <$> fextract fs
728 Error _ -> Done cnt1 <$> fextract fs
593 -- XXX The "try" may impact performance if this parser is used as a scan
730 -- XXX The "try" may impact performance if this parser is used as a scan
@@ -613,10 +750,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
614{-# INLINE_NORMAL die #-}
751{-# INLINE_NORMAL die #-}
615die :: MonadThrow m => String -> Parser m a b
752die :: MonadThrow m => String -> Parser m a b
616−die err =
753+die err = Parser undefined (pure (IError err)) undefined
617− Parser (\_ _ -> pure $ Error err) -- step
618− (pure ()) -- initial
619− (\_ -> throwM $ ParseError err) -- extract
621-- | See 'Streamly.Internal.Data.Parser.dieM'.
755-- | See 'Streamly.Internal.Data.Parser.dieM'.
@@ -624,10 +758,7 @@ die err =
625{-# INLINE dieM #-}
759{-# INLINE dieM #-}
626dieM :: MonadThrow m => m String -> Parser m a b
760dieM :: MonadThrow m => m String -> Parser m a b
627−dieM err =
761+dieM err = Parser undefined (IError <$> err) undefined
628− Parser (\_ _ -> Error <$> err) -- step
629− (pure ()) -- initial
630− (\_ -> err >>= throwM . ParseError) -- extract
632-- Note: The default implementations of "some" and "many" loop infinitely
763-- Note: The default implementations of "some" and "many" loop infinitely
633-- because of the strict pattern match on both the arguments in applicative and
764-- because of the strict pattern match on both the arguments in applicative and
@@ -659,47 +790,70 @@ instance MonadCatch m => Alternative (Parser m a) where
659 some = splitSome toList
790 some = splitSome toList
661{-# ANN type ConcatParseState Fuse #-}
792{-# ANN type ConcatParseState Fuse #-}
662−data ConcatParseState sl p = ConcatParseL sl | ConcatParseR p
793+data ConcatParseState sl m a b =
795+ | forall s. ConcatParseR (s -> a -> m (Step s b)) s (s -> m b)
664-- | See 'Streamly.Internal.Data.Parser.concatMap'.
797-- | See 'Streamly.Internal.Data.Parser.concatMap'.
666-- /Internal/
799-- /Internal/
668{-# INLINE concatMap #-}
801{-# INLINE concatMap #-}
802+concatMap :: MonadThrow m =>
669−concatMap :: Monad m => (b -> Parser m a c) -> Parser m a b -> Parser m a c
803+ (b -> Parser m a c) -> Parser m a b -> Parser m a c
670concatMap func (Parser stepL initialL extractL) = Parser step initial extract
804concatMap func (Parser stepL initialL extractL) = Parser step initial extract
808+ {-# INLINE initializeR #-}
809+ initializeR (Parser stepR initialR extractR) = do
811+ return $ case resR of
812+ IPartial sr -> IPartial $ ConcatParseR stepR sr extractR
813+ IDone br -> IDone br
814+ IError err -> IError err
674− initial = ConcatParseL <$> initialL
817+ res <- initialL
819+ IPartial s -> return $ IPartial $ ConcatParseL s
820+ IDone b -> initializeR (func b)
821+ IError err -> return $ IError err
823+ {-# INLINE initializeRL #-}
824+ initializeRL n (Parser stepR initialR extractR) = do
826+ return $ case resR of
827+ IPartial sr -> Continue n $ ConcatParseR stepR sr extractR
828+ IDone br -> Done n br
829+ IError err -> Error err
676 step (ConcatParseL st) a = do
831 step (ConcatParseL st) a = do
677 r <- stepL st a
832 r <- stepL st a
678− return $ case r of
833+ case r of
679− Partial n s -> Continue n (ConcatParseL s)
834+ Partial n s -> return $ Continue n (ConcatParseL s)
680− Continue n s -> Continue n (ConcatParseL s)
835+ Continue n s -> return $ Continue n (ConcatParseL s)
681− Done n b -> Continue n (ConcatParseR (func b))
836+ Done n b -> initializeRL n (func b)
682− Error err -> Error err
837+ Error err -> return $ Error err
684− step (ConcatParseR (Parser stepR initialR extractR)) a = do
839+ step (ConcatParseR stepR st extractR) a = do
686 r <- stepR st a
840 r <- stepR st a
687 return $ case r of
841 return $ case r of
689− Partial n (ConcatParseR (Parser stepR (return s) extractR))
842+ Partial n s -> Partial n $ ConcatParseR stepR s extractR
691− Continue n (ConcatParseR (Parser stepR (return s) extractR))
843+ Continue n s -> Continue n $ ConcatParseR stepR s extractR
692 Done n b -> Done n b
844 Done n b -> Done n b
693 Error err -> Error err
845 Error err -> Error err
847+ {-# INLINE extractP #-}
695− extract (ConcatParseR (Parser _ initialR extractR)) =
848+ extractP (Parser _ initialR extractR) = do
696− initialR >>= extractR
849+ res <- initialR
698− extract (ConcatParseL sL) = extractL sL >>= f . func
851+ IPartial s -> extractR s
699−
852+ IDone b -> return b
700− where
853+ IError err -> throwM $ ParseError err
702− f (Parser _ initialR extractR) = initialR >>= extractR
855+ extract (ConcatParseR _ s extractR) = extractR s
856+ extract (ConcatParseL sL) = extractL sL >>= extractP . func
704-- Note: The monad instance has quadratic performance complexity. It works fine
858-- Note: The monad instance has quadratic performance complexity. It works fine
705-- for small number of compositions but for a scalable implementation we need a
859-- for small number of compositions but for a scalable implementation we need a
@@ -707,7 +861,7 @@ concatMap func (Parser stepL initialL extractL) = Parser step initial extract
708-- | See documentation of 'Streamly.Internal.Data.Parser.ParserK.Types.Parser'.
862-- | See documentation of 'Streamly.Internal.Data.Parser.ParserK.Types.Parser'.
710−instance Monad m => Monad (Parser m a) where
864+instance MonadThrow m => Monad (Parser m a) where
711 {-# INLINE return #-}
865 {-# INLINE return #-}
712 return = pure
866 return = pure