@@ -112,12 +112,17 @@
112112
113113module Streamly.Internal.Data.Parser.ParserD.Type
114114 (
115+ -- * Types
115116 Initial (..)
116117 , Step (..)
117118 , Parser (..)
118119 , ParseError (..)
119120 , rmapM
120121
122+ -- * Constructors
123+ , parser
124+ , parserM
125+
121126 , fromPure
122127 , fromEffect
123128 , serialWith
@@ -160,6 +165,7 @@ import Prelude hiding (concatMap)
160165-- >>> import qualified Streamly.Prelude as Stream
161166-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse)
162167-- >>> import qualified Streamly.Internal.Data.Parser as Parser
168+-- >>> import qualified Streamly.Internal.Data.Parser.ParserD as ParserD
163169
164170-- XXX The only differences between Initial and Step types are:
165171--
@@ -348,6 +354,30 @@ instance Functor m => Functor (Parser m a) where
348354 step s b = fmap2 f (step1 s b)
349355 fmap2 g = fmap (fmap g)
350356
357+------------------------------------------------------------------------------
358+-- General parser constructors
359+------------------------------------------------------------------------------
360+
361+-- | Make a parser using a parsing step and a starting value.
362+--
363+-- /Pre-release/
364+--
365+{-# INLINE parser #-}
366+parser :: Monad m => (b -> a -> Step b b) -> Initial b b -> Parser m a b
367+parser step initial =
368+ Parser (\s a -> return $ step s a) (return initial) return
369+
370+-- | Like 'parser' but with a monadic step function.
371+--
372+-- >>> parserM step initial = ParserD.Parser step initial return
373+--
374+-- /Pre-release/
375+--
376+{-# INLINE parserM #-}
377+parserM ::
378+ Monad m => (b -> a -> m (Step b b)) -> m (Initial b b) -> Parser m a b
379+parserM step initial = Parser step initial return
380+
351381------------------------------------------------------------------------------
352382-- Mapping on the output
353383------------------------------------------------------------------------------