on master help sign in
Add maybe and either parsers
commitcc7df3cc7bb9bb7d6f874ac6e13f651ae58ad79f authorHarendra Kumar <harendra@composewell.com> dateFri 7 Aug 2020, 17:33 (6 years ago) parent2b4bd4c
2 files changed+65−2
src/Streamly/Internal/Data/Parser.hs+23−1 src/Streamly/Internal/Data/Parser/ParserD.hs+42−1
src/Streamly/Internal/Data/Parser.hs+23−1
@@ -65,6 +65,8 @@ module Streamly.Internal.Data.Parser
6565 , peek
6666 , eof
6767 , satisfy
68+ , maybe
69+ , either
6870
6971 -- * Sequence parsers
7072 --
@@ -199,7 +201,7 @@ where
199201
200202import Control.Monad.Catch (MonadCatch)
201203import Prelude
202− hiding (any, all, take, takeWhile, sequence, concatMap)
204+ hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
203205
204206import Streamly.Internal.Data.Fold.Types (Fold(..))
205207import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
@@ -328,6 +330,26 @@ eof = K.toParserK D.eof
328330satisfy :: MonadCatch m => (a -> Bool) -> Parser m a a
329331satisfy = K.toParserK . D.satisfy
330332
333+-- | Map a 'Maybe' returning function on the next element in the stream. The
334+-- parser fails if the function returns 'Nothing' otherwise returns the 'Just'
335+-- value.
336+--
337+-- /Internal/
338+--
339+{-# INLINE maybe #-}
340+maybe :: MonadCatch m => (a -> Maybe b) -> Parser m a b
341+maybe = K.toParserK . D.maybe
342+
343+-- | Map an 'Either' returning function on the next element in the stream. If
344+-- the function returns 'Left err', the parser fails with the error message
345+-- @err@ otherwise returns the 'Right' value.
346+--
347+-- /Internal/
348+--
349+{-# INLINE either #-}
350+either :: MonadCatch m => (a -> Either String b) -> Parser m a b
351+either = K.toParserK . D.either
352+
331353-------------------------------------------------------------------------------
332354-- Taking elements
333355-------------------------------------------------------------------------------
src/Streamly/Internal/Data/Parser/ParserD.hs+42−1
@@ -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-------------------------------------------------------------------------------