on master help sign in
Rename Parse type and Step constructors

Parse => Parser Keep => Yield Back => Skip

commit136bf79bab737dbdbc26df816cc65128fa1efc09 authorHarendra Kumar <harendra@composewell.com> dateMon 23 Mar 2020, 02:19 (7 years ago) parentcc8cd01
10 files changed+240−237
benchmark/Streamly/Benchmark/Data/Parser.hs+1−1 benchmark/Streamly/Benchmark/FileIO/Stream.hs+1−1 src/Streamly/Internal/Data/Fold.hs+5−5 src/Streamly/Internal/Data/Parse/Types.hs−167 src/Streamly/Internal/Data/Parse.hs → src/Streamly/Internal/Data/Parser.hs+32−32 src/Streamly/Internal/Data/Parser/Types.hs+170 src/Streamly/Internal/Data/Stream/Prelude.hs+1−1 src/Streamly/Internal/Data/Stream/StreamD.hs+24−24 src/Streamly/Internal/Prelude.hs+4−4 streamly.cabal+2−2
benchmark/Streamly/Benchmark/Data/Parser.hs+1−1
@@ -19,7 +19,7 @@ import Prelude hiding (any, all, take)
1919import qualified Streamly as S hiding (runStream)
2020import qualified Streamly.Prelude as S
2121import qualified Streamly.Internal.Data.Fold as FL
22−import qualified Streamly.Internal.Data.Parse as PR
22+import qualified Streamly.Internal.Data.Parser as PR
2323import qualified Streamly.Internal.Prelude as IP
2424
2525import Gauge
benchmark/Streamly/Benchmark/FileIO/Stream.hs+1−1
@@ -88,7 +88,7 @@ import qualified Streamly.Data.Unicode.Stream as SS
8888import qualified Streamly.Internal.Data.Unicode.Stream as IUS
8989import qualified Streamly.Internal.Memory.Unicode.Array as IUA
9090import qualified Streamly.Internal.Data.Unfold as IUF
91−import qualified Streamly.Internal.Data.Parse as PR
91+import qualified Streamly.Internal.Data.Parser as PR
9292import qualified Streamly.Internal.Prelude as IP
9393import qualified Streamly.Internal.Data.Stream.StreamD as D
9494
src/Streamly/Internal/Data/Fold.hs+5−5
@@ -228,7 +228,7 @@ import qualified Prelude
228228
229229import Streamly.Internal.Data.Pipe.Types (Pipe (..), PipeState(..))
230230import Streamly.Internal.Data.Fold.Types
231−import Streamly.Internal.Data.Parse.Types
231+import Streamly.Internal.Data.Parser.Types
232232import Streamly.Internal.Data.Strict
233233import Streamly.Internal.Data.SVar
234234
@@ -841,8 +841,8 @@ or = Fold (\x a -> return $ x || a) (return False) return
841841-- /Internal/
842842--
843843{-# INLINE take #-}
844−take :: Monad m => Int -> Fold m a b -> Parse m a b
845−take n (Fold fstep finitial fextract) = Parse step initial extract
844+take :: Monad m => Int -> Fold m a b -> Parser m a b
845+take n (Fold fstep finitial fextract) = Parser step initial extract
846846
847847 where
848848
@@ -853,8 +853,8 @@ take n (Fold fstep finitial fextract) = Parse step initial extract
853853 let i1 = i + 1
854854 s1 = Tuple' i1 res
855855 if i1 < n
856− then return $ Keep 0 s1
857− else return $ Halt 0 s1
856+ then return $ Yield 0 s1
857+ else return $ Stop 0 s1
858858
859859 extract (Tuple' _ r) = fmap Right (fextract r)
860860
src/Streamly/Internal/Data/Parse/Types.hsdeleted−167
@@ -1,167 +0,0 @@
1−{-# LANGUAGE ExistentialQuantification #-}
2−{-# LANGUAGE BangPatterns #-}
3−{-# LANGUAGE DeriveFunctor #-}
4−{-# LANGUAGE DeriveAnyClass #-}
5−{-# LANGUAGE DeriveGeneric #-}
6−
7−-- |
8−-- Module : Streamly.Parse.Types
9−-- Copyright : (c) 2019 Composewell Technologies
10−-- License : BSD3
11−-- Maintainer : streamly@composewell.com
12−-- Stability : experimental
13−-- Portability : GHC
14−--
15−-- Streaming and backtracking parsers.
16−--
17−-- A parser is a generalization of a classical left fold. A fold never fails,
18−-- it always produces a result, it has a default initial value. A parser may
19−-- terminate or fail even without producing any result.
20−
21−-- Differences between a terminating fold and a parser:
22−--
23−-- \* A Parser is a superset of terminating fold with failure and backtracking
24−-- added.
25−-- \* A fold may be upgraded to a parser but vice versa is not true.
26−-- \* A fold is not a partial function, as it may never fail.
27−-- \* A fold's Step result is simpler as it does not backtrack.
28−-- \* A fold's result type is simpler as it does not fail and it does not return
29−-- unused input count.
30−--
31−-- Parse and Zip (zipWith) is possible only if both the parses are unskipping
32−-- or are guaranteed to have outputs in sync. Or else we will have to keep the
33−-- input buffered and may have to end the zip when one of them finishes. This
34−-- is simple if the type guarantees no skip e.g. in case of classical left
35−-- folds.
36−--
37−-- Terminating folds can have Sequential and Distribute and zip style
38−-- applicatives but cannot have Alternative.
39−--
40−-- Parsers can have Sequential Applicative and Alternative but not Distribute
41−-- and zip style applicative.
42−--
43−-- We can distribute and scan/parse a stream using both folds and parsers and
44−-- merge the resulting streams using different merge strategies (e.g.
45−-- interleaving or serial).
46−
47−module Streamly.Internal.Data.Parse.Types
48− (
49− Step (..)
50− , Parse (..)
51− )
52−where
53−
54−import Fusion.Plugin.Types (Fuse(..))
55−
56−-- | The return type of a fold step. A fold is driven by a fold driver one step
57−-- at a time, at any time the driver may @extract@ and examine the result of
58−-- the fold. The fold may backtrack at any point, therefore, the driver holds
59−-- the input in a backtracking buffer. The buffer grows or shrinks based on the
60−-- return values of the fold step execution.
61−--
62−-- When a fold step is executed it generates a new state of the fold along with
63−-- a command to the fold driver. The command tells the fold driver whether to
64−-- keep the input for future backtracking or drop it. The constructors of
65−-- 'Step' represent the commands to the driver.
66−--
67−-- /Internal/
68−--
69−{-# ANN type Step Fuse #-}
70−data Step s =
71− Keep Int s -- ^ Keep @n@ most recent inputs, including the input of this
72− -- step invocation, and discard the rest. This indicates a
73− -- commit of an intermediate result of the fold. A fold cannot
74− -- fail beyond this commit point. If the fold terminates it
75− -- will return at least the result up to this commit and the
76− -- count of unused elements after that.
77− | Back Int s -- ^ Go back in the buffer by @n@ items, the count @n@
78− -- includes the input element of this step as well. The fold
79− -- driver backtracks and starts driving the fold with past
80− -- inputs from the requested point in the buffer. Note that
81− -- the driver cannot go back beyond the last commit point
82− -- created by 'Keep'.
83− | Halt Int s -- ^ Halt because the result of the fold will not change after
84− -- this point. Returns a count of unused elements which
85− -- includes the element on which 'Halt' occurred. Once a fold
86− -- halts, driving it further may produce undefined behavior.
87−
88−-- Note: Instead of returning the unused count as part of extract, we can
89−-- return it via Halt command. However, some folds may not ever halt, but they
90−-- may still have unused input after the last commit point.
91−
92−-- | A parsing fold is represented as @Parse step initial extract@. Before we
93−-- drive a fold we call the @initial@ action to retrieve the initial state of
94−-- the fold. The driver invokes @step@ with the previous state and an input
95−-- element. It results into a new state and a command to the driver represented
96−-- by 'Step' type. At any point of time the driver can call @extract@ to
97−-- inspect the result of the fold. It may result in an error or an output value
98−-- along with the count (zero or more) of last unused elements.
99−--
100−data Parse m a b =
101− forall s. Parse (s -> a -> m (Step s))
102− (m s)
103− (s -> m (Either String b))
104−
105−-- | Maps a function over the output of the fold.
106−--
107−instance Monad m => Functor (Parse m a) where
108− {-# INLINE fmap #-}
109− fmap f (Parse step initial extract) = Parse step initial (fmap3 f extract)
110−
111− where
112−
113− fmap3 g = fmap (fmap (fmap g))
114−
115− {-# INLINE (<$) #-}
116− (<$) b = \_ -> pure b
117−
118−{-# ANN type SeqParseState Fuse #-}
119−data SeqParseState sl f sr =
120− SeqParseL sl | SeqParseR f sr | SeqParseLErr String
121−
122−-- | Apply two parsing folds sequentially to an input. The input is provided to
123−-- the first parser, if the parser fails then whole composition fails. If the
124−-- parser succeeds, the remaining input is supplied to the second parser. If
125−-- the second parser succeeds the composed parser succeeds otherwise it fails.
126−--
127−instance Monad m => Applicative (Parse m a) where
128− {-# INLINE pure #-}
129− pure b = Parse (\_ _ -> return $ Halt 0 ())
130− (return ())
131− (\_ -> return $ Right b)
132−
133− {-# INLINE (<*>) #-}
134− (Parse stepL initialL extractL) <*> (Parse stepR initialR extractR) =
135− Parse step initial extract
136−
137− where
138−
139− initial = SeqParseL <$> initialL
140−
141− -- Note: For the composed parse to terminate, the left parser has to be
142− -- a terminating parser returning a Halt at some point.
143− step (SeqParseL st) a = do
144− r <- stepL st a
145− case r of
146− Keep n s -> return $ Keep n (SeqParseL s)
147− Back n s -> return $ Back n (SeqParseL s)
148− Halt n s -> do
149− res <- extractL s
150− case res of
151− Left err -> return $ Halt n (SeqParseLErr err)
152− Right f -> Back n <$> (SeqParseR f <$> initialR)
153−
154− step (SeqParseR f st) a = do
155− r <- stepR st a
156− return $ case r of
157− Keep n s -> Keep n (SeqParseR f s)
158− Back n s -> Back n (SeqParseR f s)
159− Halt n s -> Halt n (SeqParseR f s)
160−
161− step (SeqParseLErr _) _ = error "step called in SeqParseLErr"
162−
163− -- XXX bimap to add "<*>: Right parse failed" to the error message
164− extract (SeqParseR f s) = fmap (fmap f) (extractR s)
165− extract (SeqParseL _) = return $ Left "<*>: Incomplete left parse"
166− extract (SeqParseLErr err) =
167− return $ Left $ "<*>: Left parse failed\n" ++ err
src/Streamly/Internal/Data/Parse.hs → src/Streamly/Internal/Data/Parser.hsrenamed+32−32
@@ -5,8 +5,8 @@
55{-# LANGUAGE ScopedTypeVariables #-}
66
77-- |
8−-- Module : Streamly.Internal.Data.Parse
9−-- Copyright : (c) 2019 Composewell Technologies
8+-- Module : Streamly.Internal.Data.Parser
9+-- Copyright : (c) 2020 Composewell Technologies
1010-- License : BSD3
1111-- Maintainer : streamly@composewell.com
1212-- Stability : experimental
@@ -14,9 +14,9 @@
1414--
1515-- Parsers.
1616
17−module Streamly.Internal.Data.Parse
17+module Streamly.Internal.Data.Parser
1818 (
19− Parse (..)
19+ Parser (..)
2020
2121 -- * Parsers
2222 , any
@@ -36,7 +36,7 @@ where
3636
3737import Prelude
3838 hiding (any, all, takeWhile)
39−import Streamly.Internal.Data.Parse.Types (Parse(..), Step(..))
39+import Streamly.Internal.Data.Parser.Types (Parser(..), Step(..))
4040import Streamly.Internal.Data.Fold.Types (Fold(..))
4141
4242import Streamly.Internal.Data.Strict
@@ -52,33 +52,33 @@ import Streamly.Internal.Data.Strict
5252-- > Right True
5353--
5454{-# INLINABLE any #-}
55−any :: Monad m => (a -> Bool) -> Parse m a Bool
56−any predicate = Parse step initial (return . Right)
55+any :: Monad m => (a -> Bool) -> Parser m a Bool
56+any predicate = Parser step initial (return . Right)
5757 where
5858 initial = return False
5959 step s a = return $
6060 if s
61− then Halt 0 True
61+ then Stop 0 True
6262 else
6363 if predicate a
64− then Halt 0 True
65− else Keep 0 False
64+ then Stop 0 True
65+ else Yield 0 False
6666
6767-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
6868-- > Right False
6969--
7070{-# INLINABLE all #-}
71−all :: Monad m => (a -> Bool) -> Parse m a Bool
72−all predicate = Parse step initial (return . Right)
71+all :: Monad m => (a -> Bool) -> Parser m a Bool
72+all predicate = Parser step initial (return . Right)
7373 where
7474 initial = return True
7575 step s a = return $
7676 if s
7777 then
7878 if predicate a
79− then Keep 0 True
80− else Halt 0 False
81− else Halt 0 False
79+ then Yield 0 True
80+ else Stop 0 False
81+ else Stop 0 False
8282
8383-------------------------------------------------------------------------------
8484-- Taking elements
@@ -95,8 +95,8 @@ all predicate = Parse step initial (return . Right)
9595-- /Internal/
9696--
9797{-# INLINABLE takeExact #-}
98−takeExact :: Monad m => Int -> Fold m a b -> Parse m a b
99−takeExact n (Fold fstep finitial fextract) = Parse step initial extract
98+takeExact :: Monad m => Int -> Fold m a b -> Parser m a b
99+takeExact n (Fold fstep finitial fextract) = Parser step initial extract
100100
101101 where
102102
@@ -106,7 +106,7 @@ takeExact n (Fold fstep finitial fextract) = Parse step initial extract
106106 res <- fstep r a
107107 let i1 = i + 1
108108 s1 = Tuple' i1 res
109− return $ if i1 < n then Back 0 s1 else Halt 0 s1
109+ return $ if i1 < n then Skip 0 s1 else Stop 0 s1
110110
111111 extract (Tuple' i r) = fmap f (fextract r)
112112
@@ -135,8 +135,8 @@ takeExact n (Fold fstep finitial fextract) = Parse step initial extract
135135-- /Internal/
136136--
137137{-# INLINABLE takeAtLeast #-}
138−takeAtLeast :: Monad m => Int -> Fold m a b -> Parse m a b
139−takeAtLeast n (Fold fstep finitial fextract) = Parse step initial extract
138+takeAtLeast :: Monad m => Int -> Fold m a b -> Parser m a b
139+takeAtLeast n (Fold fstep finitial fextract) = Parser step initial extract
140140
141141 where
142142
@@ -146,7 +146,7 @@ takeAtLeast n (Fold fstep finitial fextract) = Parse step initial extract
146146 res <- fstep r a
147147 let i1 = i + 1
148148 s1 = Tuple' i1 res
149− return $ Back 0 s1
149+ return $ Skip 0 s1
150150
151151 extract (Tuple' i r) = fmap f (fextract r)
152152
@@ -172,17 +172,17 @@ takeAtLeast n (Fold fstep finitial fextract) = Parse step initial extract
172172-- /Internal/
173173--
174174{-# INLINABLE takeWhile #-}
175−takeWhile :: Monad m => (a -> Bool) -> Fold m a b -> Parse m a b
175+takeWhile :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
176176takeWhile predicate (Fold fstep finitial fextract) =
177− Parse step initial extract
177+ Parser step initial extract
178178
179179 where
180180
181181 initial = finitial
182182 step s a = do
183183 if predicate a
184− then Keep 0 <$> fstep s a
185− else return $ Halt 1 s
184+ then Yield 0 <$> fstep s a
185+ else return $ Stop 1 s
186186 extract s = do
187187 b <- fextract s
188188 return $ Right b
@@ -202,17 +202,17 @@ takeWhile predicate (Fold fstep finitial fextract) =
202202-- /Internal/
203203--
204204{-# INLINABLE endOn #-}
205−endOn :: Monad m => (a -> Bool) -> Fold m a b -> Parse m a b
205+endOn :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
206206endOn predicate (Fold fstep finitial fextract) =
207− Parse step initial extract
207+ Parser step initial extract
208208
209209 where
210210
211211 initial = finitial
212212 step s a = do
213213 if not (predicate a)
214− then Keep 0 <$> fstep s a
215− else return $ Halt 0 s
214+ then Yield 0 <$> fstep s a
215+ else return $ Stop 0 s
216216 extract s = do
217217 b <- fextract s
218218 return $ Right b
@@ -228,7 +228,7 @@ endOn predicate (Fold fstep finitial fextract) =
228228{-# INLINABLE endAfter #-}
229229endAfter ::
230230 -- Monad m =>
231− (a -> Bool) -> Fold m a b -> Parse m a b
231+ (a -> Bool) -> Fold m a b -> Parser m a b
232232endAfter = undefined
233233
234234-- | Keep taking elements until the predicate succeeds. Return the succeeding
@@ -242,7 +242,7 @@ endAfter = undefined
242242{-# INLINABLE endBefore #-}
243243endBefore ::
244244 -- Monad m =>
245− (a -> Bool) -> Fold m a b -> Parse m a b
245+ (a -> Bool) -> Fold m a b -> Parser m a b
246246endBefore = undefined
247247
248248-- | Distribute the input to a parse and a fold until the parse succeeds or
@@ -250,5 +250,5 @@ endBefore = undefined
250250--
251251-- /Unimplemented/
252252--
253−finishBy :: Parse m a x -> Fold m a y -> Parse m a (x, y)
253+finishBy :: Parser m a x -> Fold m a y -> Parser m a (x, y)
254254finishBy = undefined
src/Streamly/Internal/Data/Parser/Types.hsnew file+170
@@ -0,0 +1,170 @@
1+{-# LANGUAGE ExistentialQuantification #-}
2+{-# LANGUAGE BangPatterns #-}
3+{-# LANGUAGE DeriveFunctor #-}
4+{-# LANGUAGE DeriveAnyClass #-}
5+{-# LANGUAGE DeriveGeneric #-}
6+
7+-- |
8+-- Module : Streamly.Parser.Types
9+-- Copyright : (c) 2020 Composewell Technologies
10+-- License : BSD3
11+-- Maintainer : streamly@composewell.com
12+-- Stability : experimental
13+-- Portability : GHC
14+--
15+-- Streaming and backtracking parsers.
16+--
17+-- The 'Parser' type or a parsing fold is a generalization of the 'Fold' type.
18+-- The 'Fold' type always succeeds on each input. Therefore it does not need to
19+-- buffer the input. In contrast, a 'Parser' may fail and backtrack to replay
20+-- the input again to explore another branch of the parser. Therefore, it needs
21+-- to buffer the input.
22+--
23+-- The 'Parser' type is an extension of the 'Fold' type. The 'Step' functor
24+-- for the 'Parser' type has been specifically designed for stream parsing
25+-- applications, assuming the input to be a seuqentially read stream and
26+-- potentially buffering a contiguous segment of the stream based on the
27+-- parser's need.
28+--
29+-- To provide richer communication with the input stream, the 'Step' functor of
30+-- a 'Parser' provides more powerful commands to manipulate the input stream
31+-- after each step invocation. It allows the fold driver to:
32+--
33+-- 1. Buffer the input until explicitly asked to drop the input
34+-- 2. Drop the input stream beyond a "point of no return" in the history
35+-- because the input till that point has been consumed irrevocably.
36+-- 2. Go back in the buffered stream upto the point of no return.
37+--
38+-- Based on application requirements it should be possible to design even a
39+-- richer interface to manipulate the input stream/buffer. For example, we
40+-- could randomly seek into the stream in the forward or reverse directions or
41+-- we can even seek to the end or from the end or seek from the beginning.
42+
43+-- We can distribute and scan/parse a stream using both folds and parsers and
44+-- merge the resulting streams using different merge strategies (e.g.
45+-- interleaving or serial).
46+
47+module Streamly.Internal.Data.Parser.Types
48+ (
49+ Step (..)
50+ , Parser (..)
51+ )
52+where
53+
54+import Fusion.Plugin.Types (Fuse(..))
55+
56+-- | The return type of a 'Parser' step.
57+--
58+-- A parser is driven by a parse driver one step at a time, at any time the
59+-- driver may @extract@ the result of the parser. The parser may ask the driver
60+-- to backtrack at any point, therefore, the driver holds the input up to a
61+-- point of no return in a backtracking buffer. The buffer grows or shrinks
62+-- based on the return values of the parser step execution.
63+--
64+-- When a parser step is executed it generates a new state of the parse result
65+-- along with a command to the driver. The command tells the driver whether to
66+-- keep the input stream for backtracking or drop it, and how much to keep. The
67+-- constructors of 'Step' represent the commands to the driver.
68+--
69+-- /Internal/
70+--
71+{-# ANN type Step Fuse #-}
72+data Step s =
73+ Yield Int s
74+ -- ^ @Yield offset state@ indicates that the parser has yielded a new
75+ -- result which is a point of no return. The result can be extracted
76+ -- using @extract@. The driver drops the buffer except @offset@ elements
77+ -- before the current position in stream. The rule is that if a parser
78+ -- has yielded at least once it cannot return a failure result.
79+
80+ | Skip Int s
81+ -- ^ @Skip offset state@ indicates that the parser has consumed the current
82+ -- input but no new result has been generated. A new @state@ is generated.
83+ -- However, if we use @extract@ on @state@ it will generate a result from
84+ -- the previous @Yield@. When @offset@ is non-zero it is a backward offset
85+ -- from the current position in the stream from which the driver will feed
86+ -- the next input to the parser. The offset cannot be beyond the latest
87+ -- point of no return created by @Yield@.
88+
89+ | Stop Int s
90+ -- ^ @Stop offset state@ asks the driver to stop driving the parser because
91+ -- it has reached a fixed point and further input will not change the
92+ -- result. @offset@ is the count of unused elements which includes the
93+ -- element on which 'Stop' occurred. Once a fold stops, driving it further
94+ -- may produce undefined behavior.
95+
96+-- | A parsing fold is represented as @Parser step initial extract@. Before we
97+-- drive a parser we call the @initial@ action to retrieve the initial state of
98+-- the fold. The driver invokes @step@ with the state returned by the previous
99+-- step and the next input element. It results into a new state and a command
100+-- to the driver represented by 'Step' type. At any point of time the driver
101+-- can call @extract@ to inspect the result of the fold. It may result in an
102+-- error or an output value.
103+--
104+data Parser m a b =
105+ forall s. Parser (s -> a -> m (Step s)) (m s) (s -> m (Either String b))
106+
107+-- | Maps a function over the output of the fold.
108+--
109+instance Monad m => Functor (Parser m a) where
110+ {-# INLINE fmap #-}
111+ fmap f (Parser step initial extract) =
112+ Parser step initial (fmap3 f extract)
113+
114+ where
115+
116+ fmap3 g = fmap (fmap (fmap g))
117+
118+ {-# INLINE (<$) #-}
119+ (<$) b = \_ -> pure b
120+
121+{-# ANN type SeqParseState Fuse #-}
122+data SeqParseState sl f sr =
123+ SeqParseL sl | SeqParseR f sr | SeqParseLErr String
124+
125+-- | Apply two parsing folds sequentially to an input. The input is provided to
126+-- the first parser, if the parser fails then whole composition fails. If the
127+-- parser succeeds, the remaining input is supplied to the second parser. If
128+-- the second parser succeeds the composed parser succeeds otherwise it fails.
129+--
130+instance Monad m => Applicative (Parser m a) where
131+ {-# INLINE pure #-}
132+ pure b = Parser (\_ _ -> return $ Stop 0 ())
133+ (return ())
134+ (\_ -> return $ Right b)
135+
136+ {-# INLINE (<*>) #-}
137+ (Parser stepL initialL extractL) <*> (Parser stepR initialR extractR) =
138+ Parser step initial extract
139+
140+ where
141+
142+ initial = SeqParseL <$> initialL
143+
144+ -- Note: For the composed parse to terminate, the left parser has to be
145+ -- a terminating parser returning a Halt at some point.
146+ step (SeqParseL st) a = do
147+ r <- stepL st a
148+ case r of
149+ Yield n s -> return $ Yield n (SeqParseL s)
150+ Skip n s -> return $ Skip n (SeqParseL s)
151+ Stop n s -> do
152+ res <- extractL s
153+ case res of
154+ Left err -> return $ Stop n (SeqParseLErr err)
155+ Right f -> Skip n <$> (SeqParseR f <$> initialR)
156+
157+ step (SeqParseR f st) a = do
158+ r <- stepR st a
159+ return $ case r of
160+ Yield n s -> Yield n (SeqParseR f s)
161+ Skip n s -> Skip n (SeqParseR f s)
162+ Stop n s -> Stop n (SeqParseR f s)
163+
164+ step (SeqParseLErr _) _ = error "step called in SeqParseLErr"
165+
166+ -- XXX bimap to add "<*>: Right parse failed" to the error message
167+ extract (SeqParseR f s) = fmap (fmap f) (extractR s)
168+ extract (SeqParseL _) = return $ Left "<*>: Incomplete left parse"
169+ extract (SeqParseLErr err) =
170+ return $ Left $ "<*>: Left parse failed\n" ++ err
src/Streamly/Internal/Data/Stream/Prelude.hs+1−1
@@ -73,7 +73,7 @@ import Prelude hiding (foldr, minimum, maximum)
7373import qualified Prelude
7474
7575import Streamly.Internal.Data.Fold.Types (Fold (..))
76−import Streamly.Internal.Data.Parse.Types (Step)
76+import Streamly.Internal.Data.Parser.Types (Step)
7777
7878#ifdef USE_STREAMK_ONLY
7979import qualified Streamly.Internal.Data.Stream.StreamK as S
src/Streamly/Internal/Data/Stream/StreamD.hs+24−24
@@ -362,7 +362,7 @@ import Streamly.Internal.Data.Time.Units
362362import Streamly.Internal.Data.Atomics (atomicModifyIORefCAS_)
363363import Streamly.Internal.Memory.Array.Types (Array(..))
364364import Streamly.Internal.Data.Fold.Types (Fold(..))
365−import Streamly.Internal.Data.Parse.Types (Parse(..))
365+import Streamly.Internal.Data.Parser.Types (Parser(..))
366366import Streamly.Internal.Data.Pipe.Types (Pipe(..), PipeState(..))
367367import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
368368import Streamly.Internal.Data.Time.Units
@@ -379,7 +379,7 @@ import qualified Streamly.Internal.Memory.Array.Types as A
379379import qualified Streamly.Internal.Data.Fold as FL
380380import qualified Streamly.Memory.Ring as RB
381381import qualified Streamly.Internal.Data.Stream.StreamK as K
382−import qualified Streamly.Internal.Data.Parse.Types as PR
382+import qualified Streamly.Internal.Data.Parser.Types as PR
383383
384384------------------------------------------------------------------------------
385385-- Construction
@@ -992,17 +992,17 @@ parselMx' pstep initial extract (Stream step state) = do
992992 Yield x s -> do
993993 pRes <- pstep pst x
994994 case pRes of
995− -- PR.Keep 0 pst1 -> go SPEC s [] pst1
996− PR.Keep n pst1 -> do
995+ -- PR.Yield 0 pst1 -> go SPEC s [] pst1
996+ PR.Yield n pst1 -> do
997997 assert (n <= length (x:buf)) (return ())
998998 go SPEC s (Prelude.take n (x:buf)) pst1
999− -- PR.Back 0 pst1 -> go SPEC s (x:buf) pst1
1000− PR.Back n pst1 -> do
999+ -- PR.Skip 0 pst1 -> go SPEC s (x:buf) pst1
1000+ PR.Skip n pst1 -> do
10011001 assert (n <= length (x:buf)) (return ())
10021002 let (src0, buf1) = splitAt n (x:buf)
10031003 src = Prelude.reverse src0
10041004 gobuf SPEC s buf1 src pst1
1005− PR.Halt _ pst1 -> extract pst1
1005+ PR.Stop _ pst1 -> extract pst1
10061006 Skip s -> go SPEC s buf pst
10071007 Stop -> extract pst
10081008
@@ -1010,17 +1010,17 @@ parselMx' pstep initial extract (Stream step state) = do
10101010 gobuf !_ s buf (x:xs) !pst = do
10111011 pRes <- pstep pst x
10121012 case pRes of
1013− -- PR.Keep 0 pst1 -> go SPEC s [] pst1
1014− PR.Keep n pst1 -> do
1013+ -- PR.Yield 0 pst1 -> go SPEC s [] pst1
1014+ PR.Yield n pst1 -> do
10151015 assert (n <= length (x:buf)) (return ())
10161016 gobuf SPEC s (Prelude.take n (x:buf)) xs pst1
1017− -- PR.Back 0 pst1 -> gobuf SPEC s (x:buf) xs pst1
1018− PR.Back n pst1 -> do
1017+ -- PR.Skip 0 pst1 -> gobuf SPEC s (x:buf) xs pst1
1018+ PR.Skip n pst1 -> do
10191019 assert (n <= length (x:buf)) (return ())
10201020 let (src0, buf1) = splitAt n (x:buf)
10211021 src = Prelude.reverse src0 ++ xs
10221022 gobuf SPEC s buf1 src pst1
1023− PR.Halt _ pst1 -> extract pst1
1023+ PR.Stop _ pst1 -> extract pst1
10241024
10251025------------------------------------------------------------------------------
10261026-- Repeated parsing
@@ -1037,10 +1037,10 @@ data ParseChunksState x inpBuf st pst =
10371037{-# INLINE_NORMAL parseChunks #-}
10381038parseChunks
10391039 :: Monad m
1040− => Parse m a b
1040+ => Parser m a b
10411041 -> Stream m a
10421042 -> Stream m b
1043−parseChunks (Parse pstep initial extract) (Stream step state) =
1043+parseChunks (Parser pstep initial extract) (Stream step state) =
10441044 Stream stepOuter (ParseChunksInit [] state)
10451045
10461046 where
@@ -1064,20 +1064,20 @@ parseChunks (Parse pstep initial extract) (Stream step state) =
10641064 Yield x s -> do
10651065 pRes <- pstep pst x
10661066 case pRes of
1067− -- PR.Keep 0 pst1 -> go SPEC s [] pst1
1068− PR.Keep n pst1 -> do
1067+ -- PR.Yield 0 pst1 -> go SPEC s [] pst1
1068+ PR.Yield n pst1 -> do
10691069 assert (n <= length (x:buf)) (return ())
10701070 let buf1 = Prelude.take n (x:buf)
10711071 return $ Skip $ ParseChunksStream s buf1 pst1
1072− -- PR.Back 0 pst1 ->
1072+ -- PR.Skip 0 pst1 ->
10731073 -- return $ Skip $ ParseChunksStream s (x:buf) pst1
1074− PR.Back n pst1 -> do
1074+ PR.Skip n pst1 -> do
10751075 assert (n <= length (x:buf)) (return ())
10761076 let (src0, buf1) = splitAt n (x:buf)
10771077 src = Prelude.reverse src0
10781078 return $ Skip $ ParseChunksBuf src s buf1 pst1
10791079 -- XXX Halt 0 common case?
1080− PR.Halt n pst1 -> do
1080+ PR.Stop n pst1 -> do
10811081 res <- extract pst1
10821082 case res of
10831083 Left err -> error err
@@ -1102,19 +1102,19 @@ parseChunks (Parse pstep initial extract) (Stream step state) =
11021102 stepOuter _ (ParseChunksBuf (x:xs) s buf pst) = do
11031103 pRes <- pstep pst x
11041104 case pRes of
1105− -- PR.Keep 0 pst1 ->
1106− PR.Keep n pst1 -> do
1105+ -- PR.Yield 0 pst1 ->
1106+ PR.Yield n pst1 -> do
11071107 assert (n <= length (x:buf)) (return ())
11081108 let buf1 = Prelude.take n (x:buf)
11091109 return $ Skip $ ParseChunksBuf xs s buf1 pst1
1110− -- PR.Back 0 pst1 -> return $ Skip $ ParseChunksBuf xs s (x:buf) pst1
1111− PR.Back n pst1 -> do
1110+ -- PR.Skip 0 pst1 -> return $ Skip $ ParseChunksBuf xs s (x:buf) pst1
1111+ PR.Skip n pst1 -> do
11121112 assert (n <= length (x:buf)) (return ())
11131113 let (src0, buf1) = splitAt n (x:buf)
11141114 src = Prelude.reverse src0 ++ xs
11151115 return $ Skip $ ParseChunksBuf src s buf1 pst1
11161116 -- XXX have 0 case
1117− PR.Halt n pst1 -> do
1117+ PR.Stop n pst1 -> do
11181118 res <- extract pst1
11191119 case res of
11201120 Left err -> error err
src/Streamly/Internal/Prelude.hs+4−4
@@ -539,7 +539,7 @@ import qualified System.IO as IO
539539
540540import Streamly.Internal.Data.Stream.Enumeration (Enumerable(..), enumerate, enumerateTo)
541541import Streamly.Internal.Data.Fold.Types (Fold (..), Fold2 (..))
542−import Streamly.Internal.Data.Parse.Types (Parse (..))
542+import Streamly.Internal.Data.Parser.Types (Parser (..))
543543import Streamly.Internal.Data.Unfold.Types (Unfold)
544544import Streamly.Internal.Memory.Array.Types (Array, writeNUnsafe)
545545-- import Streamly.Memory.Ring (Ring)
@@ -1202,8 +1202,8 @@ runSink = fold . toFold
12021202-- /Internal/
12031203--
12041204{-# INLINE parse #-}
1205−parse :: Monad m => Parse m a b -> SerialT m a -> m (Either String b)
1206−parse (Parse step initial extract) = P.parselMx' step initial extract
1205+parse :: Monad m => Parser m a b -> SerialT m a -> m (Either String b)
1206+parse (Parser step initial extract) = P.parselMx' step initial extract
12071207
12081208------------------------------------------------------------------------------
12091209-- Specialized folds
@@ -3129,7 +3129,7 @@ concatMapTreeYieldLeavesWith combine f = concatMapLoopWith combine f yield
31293129{-# INLINE parseChunks #-}
31303130parseChunks
31313131 :: (IsStream t, Monad m)
3132− => Parse m a b
3132+ => Parser m a b
31333133 -> t m a
31343134 -> t m b
31353135parseChunks f m = D.fromStreamD $ D.parseChunks f (D.toStreamD m)
streamly.cabal+2−2
@@ -324,8 +324,8 @@ library
324324 , Streamly.Internal.Memory.ArrayStream
325325 , Streamly.Internal.Data.Fold.Types
326326 , Streamly.Internal.Data.Fold
327− , Streamly.Internal.Data.Parse
328− , Streamly.Internal.Data.Parse.Types
327+ , Streamly.Internal.Data.Parser
328+ , Streamly.Internal.Data.Parser.Types
329329 , Streamly.Internal.Data.Sink.Types
330330 , Streamly.Internal.Data.Sink
331331