@@ -30,6 +30,8 @@ module Streamly.Internal.Data.Parser.ParserD
3030 , peek
3131 , eof
3232 , satisfy
33+ , maybe
34+ , either
3335
3436 -- * Sequence parsers
3537 --
@@ -158,7 +160,8 @@ where
158160
159161import Control.Exception (assert)
160162import Control.Monad.Catch (MonadCatch, MonadThrow(..))
161−import Prelude hiding (any, all, take, takeWhile, sequence, concatMap)
163+import Prelude
164+ hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
162165import Streamly.Internal.Data.Fold.Types (Fold(..))
163166
164167import Streamly.Internal.Data.Parser.ParserD.Tee
@@ -258,6 +261,44 @@ satisfy predicate = Parser step initial extract
258261
259262 extract _ = throwM $ ParseError "satisfy: end of input"
260263
264+-- | See 'Streamly.Internal.Data.Parser.maybe'.
265+--
266+-- /Internal/
267+--
268+{-# INLINE maybe #-}
269+maybe :: MonadThrow m => (a -> Maybe b) -> Parser m a b
270+maybe parser = Parser step initial extract
271+
272+ where
273+
274+ initial = return ()
275+
276+ step () a = return $
277+ case parser a of
278+ Just b -> Done 0 b
279+ Nothing -> Error "maybe: predicate failed"
280+
281+ extract _ = throwM $ ParseError "maybe: end of input"
282+
283+-- | See 'Streamly.Internal.Data.Parser.either'.
284+--
285+-- /Internal/
286+--
287+{-# INLINE either #-}
288+either :: MonadThrow m => (a -> Either String b) -> Parser m a b
289+either parser = Parser step initial extract
290+
291+ where
292+
293+ initial = return ()
294+
295+ step () a = return $
296+ case parser a of
297+ Right b -> Done 0 b
298+ Left err -> Error $ "either: " ++ err
299+
300+ extract _ = throwM $ ParseError "either: end of input"
301+
261302-------------------------------------------------------------------------------
262303-- Taking elements
263304-------------------------------------------------------------------------------