on master help sign in
Add maybe and either parsers
cc7df3cHarendra Kumar
src/Streamly/Internal/Data/Parser.hs+23−1
@@ -65,6 +65,8 @@ module Streamly.Internal.Data.Parser
65 , peek
65 , peek
66 , eof
66 , eof
67 , satisfy
67 , satisfy
68+ , maybe
69+ , either
68
70
69 -- * Sequence parsers
71 -- * Sequence parsers
70 --
72 --
@@ -199,7 +201,7 @@ where
199
201
200import Control.Monad.Catch (MonadCatch)
202import Control.Monad.Catch (MonadCatch)
201import Prelude
203import Prelude
202− hiding (any, all, take, takeWhile, sequence, concatMap)
204+ hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
203
205
204import Streamly.Internal.Data.Fold.Types (Fold(..))
206import Streamly.Internal.Data.Fold.Types (Fold(..))
205import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
207import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
@@ -328,6 +330,26 @@ eof = K.toParserK D.eof
328satisfy :: MonadCatch m => (a -> Bool) -> Parser m a a
330satisfy :: MonadCatch m => (a -> Bool) -> Parser m a a
329satisfy = K.toParserK . D.satisfy
331satisfy = K.toParserK . D.satisfy
330
332
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+
331-------------------------------------------------------------------------------
353-------------------------------------------------------------------------------
332-- Taking elements
354-- Taking elements
333-------------------------------------------------------------------------------
355-------------------------------------------------------------------------------
src/Streamly/Internal/Data/Parser/ParserD.hs+42−1
@@ -30,6 +30,8 @@ module Streamly.Internal.Data.Parser.ParserD
30 , peek
30 , peek
31 , eof
31 , eof
32 , satisfy
32 , satisfy
33+ , maybe
34+ , either
33
35
34 -- * Sequence parsers
36 -- * Sequence parsers
35 --
37 --
@@ -158,7 +160,8 @@ where
158
160
159import Control.Exception (assert)
161import Control.Exception (assert)
160import Control.Monad.Catch (MonadCatch, MonadThrow(..))
162import Control.Monad.Catch (MonadCatch, MonadThrow(..))
163+import Prelude
161−import Prelude hiding (any, all, take, takeWhile, sequence, concatMap)
164+ hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
162import Streamly.Internal.Data.Fold.Types (Fold(..))
165import Streamly.Internal.Data.Fold.Types (Fold(..))
163
166
164import Streamly.Internal.Data.Parser.ParserD.Tee
167import Streamly.Internal.Data.Parser.ParserD.Tee
@@ -258,6 +261,44 @@ satisfy predicate = Parser step initial extract
258
261
259 extract _ = throwM $ ParseError "satisfy: end of input"
262 extract _ = throwM $ ParseError "satisfy: end of input"
260
263
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+
261-------------------------------------------------------------------------------
302-------------------------------------------------------------------------------
262-- Taking elements
303-- Taking elements
263-------------------------------------------------------------------------------
304-------------------------------------------------------------------------------