on master help sign in
Add eqBy to match a sequence
commit007343a84e95b094b0388deb4dd86c11997f8f2d authorHarendra Kumar <harendra@composewell.com> dateThu 9 Apr 2020, 13:58 (7 years ago) parentc8bbb0a
1 file changed+34
src/Streamly/Internal/Data/Parser.hs+34
src/Streamly/Internal/Data/Parser.hs+34
@@ -76,6 +76,10 @@ module Streamly.Internal.Data.Parser
7676 , sepWithPrefix
7777 , wordBy
7878 , groupBy
79+ , eqBy
80+ -- , prefixOf -- match any prefix of a given string
81+ -- , suffixOf -- match any suffix of a given string
82+ -- , infixOf -- match any substring of a given string
7983
8084 -- Second order parsers (parsers using parsers)
8185 -- * Binary Combinators
@@ -572,6 +576,36 @@ groupBy ::
572576 (a -> a -> Bool) -> Fold m a b -> Parser m a b
573577groupBy = undefined
574578
579+-- XXX use an Unfold instead of a list?
580+-- XXX custom combinators for matching list, array and stream?
581+--
582+-- | Match the given sequence of elements using the given comparison function.
583+--
584+-- /Internal/
585+--
586+{-# INLINE eqBy #-}
587+eqBy :: MonadThrow m => (a -> a -> Bool) -> [a] -> Parser m a ()
588+eqBy cmp str = Parser step initial extract
589+
590+ where
591+
592+ initial = return str
593+
594+ step [] _ = error "Bug: unreachable"
595+ step [x] a = return $
596+ if x `cmp` a
597+ then Stop 0 ()
598+ else Error $
599+ "eqBy: failed, at the last element"
600+ step (x:xs) a = return $
601+ if x `cmp` a
602+ then Skip 0 xs
603+ else Error $
604+ "eqBy: failed, yet to match " ++ show (length xs) ++ " elements"
605+
606+ extract xs = throwM $ ParseError $
607+ "eqBy: end of input, yet to match " ++ show (length xs) ++ " elements"
608+
575609-------------------------------------------------------------------------------
576610-- nested parsers
577611-------------------------------------------------------------------------------