on master help sign in
Add parser to fold conversion function, toFold
7bf60ffHarendra Kumar
src/Streamly/Internal/Data/Parser.hs+21−1
@@ -51,6 +51,9 @@ module Streamly.Internal.Data.Parser
51 , D.ParseError (..)
51 , D.ParseError (..)
52 , D.Step (..)
52 , D.Step (..)
53
53
54+ -- * Downgrade to Fold
55+ , toFold
56+
54 -- First order parsers
57 -- First order parsers
55 -- * Accumulators
58 -- * Accumulators
56 , fromFold
59 , fromFold
@@ -196,7 +199,7 @@ module Streamly.Internal.Data.Parser
196 )
199 )
197where
200where
198
201
199−import Control.Monad.Catch (MonadCatch)
202+import Control.Monad.Catch (MonadCatch, MonadThrow)
200import Prelude
203import Prelude
201 hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
204 hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
202
205
@@ -216,6 +219,23 @@ import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
216-- >>> import qualified Streamly.Data.Fold as Fold
219-- >>> import qualified Streamly.Data.Fold as Fold
217-- >>> import qualified Streamly.Internal.Data.Parser as Parser
220-- >>> import qualified Streamly.Internal.Data.Parser as Parser
218
221
222+-------------------------------------------------------------------------------
223+-- Downgrade a parser to a Fold
224+-------------------------------------------------------------------------------
225+--
226+-- | Make a 'Fold' from a 'Parser'. The fold just throws an exception if the
227+-- parser fails or tries to backtrack.
228+--
229+-- This can be useful in combinators that accept a Fold and we know that a
230+-- Parser cannot fail or failure exception is acceptable as there is no way to
231+-- recover.
232+--
233+-- /Pre-release/
234+--
235+{-# INLINE toFold #-}
236+toFold :: MonadThrow m => Parser m a b -> Fold m a b
237+toFold p = D.toFold $ K.fromParserK p
238+
219-------------------------------------------------------------------------------
239-------------------------------------------------------------------------------
220-- Upgrade folds to parses
240-- Upgrade folds to parses
221-------------------------------------------------------------------------------
241-------------------------------------------------------------------------------
src/Streamly/Internal/Data/Parser/ParserD.hs+46−1
@@ -18,6 +18,9 @@ module Streamly.Internal.Data.Parser.ParserD
18 , Initial (..)
18 , Initial (..)
19 , rmapM
19 , rmapM
20
20
21+ -- * Downgrade to Fold
22+ , toFold
23+
21 -- First order parsers
24 -- First order parsers
22 -- * Accumulators
25 -- * Accumulators
23 , fromFold
26 , fromFold
@@ -162,7 +165,7 @@ module Streamly.Internal.Data.Parser.ParserD
162 )
165 )
163where
166where
164
167
165−import Control.Exception (assert)
168+import Control.Exception (assert, Exception)
166import Control.Monad.Catch (MonadCatch, MonadThrow(..))
169import Control.Monad.Catch (MonadCatch, MonadThrow(..))
167import Fusion.Plugin.Types (Fuse(..))
170import Fusion.Plugin.Types (Fuse(..))
168import Streamly.Internal.Data.Fold.Type (Fold(..))
171import Streamly.Internal.Data.Fold.Type (Fold(..))
@@ -184,6 +187,48 @@ import Streamly.Internal.Data.Parser.ParserD.Type
184-- >>> import qualified Streamly.Data.Fold as Fold
187-- >>> import qualified Streamly.Data.Fold as Fold
185-- >>> import qualified Streamly.Internal.Data.Parser as Parser
188-- >>> import qualified Streamly.Internal.Data.Parser as Parser
186
189
190+-------------------------------------------------------------------------------
191+-- Downgrade a parser to a Fold
192+-------------------------------------------------------------------------------
193+
194+data ParserToFoldError =
195+ InitialError String
196+ | PartialError Int
197+ | ContinueError Int
198+ | DoneError Int
199+ | ErrorError String
200+ deriving Show
201+
202+instance Exception ParserToFoldError
203+
204+-- | See 'Streamly.Internal.Data.Parser.toFold'.
205+--
206+-- /Internal/
207+--
208+{-# INLINE toFold #-}
209+toFold :: MonadThrow m => Parser m a b -> Fold m a b
210+toFold (Parser pstep pinitial pextract) = Fold step initial pextract
211+
212+ where
213+
214+ initial = do
215+ r <- pinitial
216+ case r of
217+ IPartial s -> return $ FL.Partial s
218+ IDone b -> return $ FL.Done b
219+ IError err -> throwM $ InitialError err
220+
221+ step st a = do
222+ r <- pstep st a
223+ case r of
224+ Partial 0 s -> return $ FL.Partial s
225+ Continue 0 s -> return $ FL.Partial s
226+ Done 0 b -> return $ FL.Done b
227+ Partial n _ -> throwM $ PartialError n
228+ Continue n _ -> throwM $ ContinueError n
229+ Done n _ -> throwM $ DoneError n
230+ Error err -> throwM $ ErrorError err
231+
187-------------------------------------------------------------------------------
232-------------------------------------------------------------------------------
188-- Upgrade folds to parses
233-- Upgrade folds to parses
189-------------------------------------------------------------------------------
234-------------------------------------------------------------------------------