on master help sign in
Implement satisfy and maybe in terms of either
commit2f9709bada061367a23669b6c80ecfc8a3337395 authorHarendra Kumar <harendra@composewell.com> dateWed 18 May 2022, 15:51 (4 years ago) parentf4d5b36
2 files changed+45−27
core/src/Streamly/Internal/Data/Parser.hs+9 core/src/Streamly/Internal/Data/Parser/ParserD.hs+36−27
core/src/Streamly/Internal/Data/Parser.hs+9
@@ -255,6 +255,7 @@ import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
255255-- >>> import Prelude hiding (any, all, dropWhile, take, takeWhile, sequence, concatMap, maybe, either, filter)
256256-- >>> import Control.Applicative ((<|>))
257257-- >>> import Data.Char (isSpace)
258+-- >>> import qualified Data.Maybe as Maybe
258259-- >>> import qualified Streamly.Prelude as Stream
259260-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, parseMany)
260261-- >>> import qualified Streamly.Internal.Data.Fold as Fold
@@ -409,12 +410,17 @@ eof = D.toParserK D.eof
409410-- >>> Stream.parse (Parser.satisfy (== 1)) $ Stream.fromList [1,0,1]
410411-- 1
411412--
413+-- >>> toMaybe f x = if f x then Just x else Nothing
414+-- >>> satisfy f = Parser.maybe (toMaybe f)
415+--
412416-- /Pre-release/
413417--
414418{-# INLINE satisfy #-}
415419satisfy :: MonadCatch m => (a -> Bool) -> Parser m a a
416420satisfy = D.toParserK . D.satisfy
417421
422+-- XXX Change this to "next".
423+--
418424-- | Consume one element from the head of the stream. Fails if it encounters
419425-- end of input.
420426--
@@ -487,6 +493,9 @@ next = D.toParserK D.next
487493-- parser fails if the function returns 'Nothing' otherwise returns the 'Just'
488494-- value.
489495--
496+-- >>> toEither = Maybe.maybe (Left "maybe: predicate failed") Right
497+-- >>> maybe f = Parser.either (toEither . f)
498+--
490499-- /Pre-release/
491500--
492501{-# INLINE maybe #-}
core/src/Streamly/Internal/Data/Parser/ParserD.hs+36−27
@@ -221,6 +221,7 @@ import Streamly.Internal.Data.Parser.ParserD.Type
221221-- >>> :m
222222-- >>> :set -package streamly
223223-- >>> import Prelude hiding ()
224+-- >>> import qualified Data.Maybe as Maybe
224225-- >>> import qualified Streamly.Prelude as Stream
225226-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
226227-- >>> import qualified Streamly.Data.Fold as Fold
@@ -330,25 +331,6 @@ eof = Parser step initial return
330331
331332 step () _ = return $ Error "eof: not at end of input"
332333
333−-- | See 'Streamly.Internal.Data.Parser.satisfy'.
334−--
335−-- /Pre-release/
336−--
337−{-# INLINE satisfy #-}
338−satisfy :: MonadThrow m => (a -> Bool) -> Parser m a a
339−satisfy predicate = Parser step initial extract
340−
341− where
342−
343− initial = return $ IPartial ()
344−
345− step () a = return $
346− if predicate a
347− then Done 0 a
348− else Error "satisfy: predicate failed"
349−
350− extract _ = throwM $ ParseError "satisfy: end of input"
351−
352334-- | See 'Streamly.Internal.Data.Parser.next'.
353335--
354336-- /Pre-release/
@@ -361,12 +343,35 @@ next = Parser step initial extract
361343 step _ a = pure $ Done 0 (Just a)
362344 extract _ = pure Nothing
363345
346+-- | See 'Streamly.Internal.Data.Parser.either'.
347+--
348+-- /Pre-release/
349+--
350+{-# INLINE either #-}
351+either :: MonadThrow m => (a -> Either String b) -> Parser m a b
352+either f = Parser step initial extract
353+
354+ where
355+
356+ initial = return $ IPartial ()
357+
358+ step () a = return $
359+ case f a of
360+ Right b -> Done 0 b
361+ Left err -> Error err
362+
363+ extract _ = throwM $ ParseError "end of input"
364+
364365-- | See 'Streamly.Internal.Data.Parser.maybe'.
365366--
367+-- >>> toEither = Maybe.maybe (Left "maybe: predicate failed") Right
368+-- >>> maybe f = Parser.either (toEither . f)
369+--
366370-- /Pre-release/
367371--
368372{-# INLINE maybe #-}
369373maybe :: MonadThrow m => (a -> Maybe b) -> Parser m a b
374+-- maybe f = either (Maybe.maybe (Left "maybe: predicate failed") Right . f)
370375maybe parserF = Parser step initial extract
371376
372377 where
@@ -380,24 +385,28 @@ maybe parserF = Parser step initial extract
380385
381386 extract _ = throwM $ ParseError "maybe: end of input"
382387
383−-- | See 'Streamly.Internal.Data.Parser.either'.
388+-- | See 'Streamly.Internal.Data.Parser.satisfy'.
389+--
390+-- >>> toMaybe f x = if f x then Just x else Nothing
391+-- >>> satisfy f = Parser.maybe (toMaybe f)
384392--
385393-- /Pre-release/
386394--
387−{-# INLINE either #-}
388−either :: MonadThrow m => (a -> Either String b) -> Parser m a b
389−either parserF = Parser step initial extract
395+{-# INLINE satisfy #-}
396+satisfy :: MonadThrow m => (a -> Bool) -> Parser m a a
397+-- satisfy predicate = maybe (\a -> if predicate a then Just a else Nothing)
398+satisfy predicate = Parser step initial extract
390399
391400 where
392401
393402 initial = return $ IPartial ()
394403
395404 step () a = return $
396− case parserF a of
397− Right b -> Done 0 b
398− Left err -> Error $ "either: " ++ err
405+ if predicate a
406+ then Done 0 a
407+ else Error "satisfy: predicate failed"
399408
400− extract _ = throwM $ ParseError "either: end of input"
409+ extract _ = throwM $ ParseError "satisfy: end of input"
401410
402411-------------------------------------------------------------------------------
403412-- Taking elements