on master help sign in
Add a stream equality match parser
commit5dbf2ac7f9cac2327bfb34830490f6cc8fee6c93 authorHarendra Kumar <harendra@composewell.com> dateWed 4 May 2022, 01:21 (4 years ago) parent734df11
1 file changed+44
core/src/Streamly/Internal/Data/Parser/ParserD.hs+44
core/src/Streamly/Internal/Data/Parser/ParserD.hs+44
@@ -77,6 +77,7 @@ module Streamly.Internal.Data.Parser.ParserD
7777 , groupByRolling
7878 , groupByRollingEither
7979 , eqBy
80+ , matchBy
8081 -- , prefixOf -- match any prefix of a given string
8182 -- , suffixOf -- match any suffix of a given string
8283 -- , infixOf -- match any substring of a given string
@@ -176,9 +177,11 @@ import Control.Monad (when)
176177import Control.Monad.Catch (MonadCatch, MonadThrow(..))
177178import Fusion.Plugin.Types (Fuse(..))
178179import Streamly.Internal.Data.Fold.Type (Fold(..))
180+import Streamly.Internal.Data.SVar.Type (defState)
179181import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
180182
181183import qualified Streamly.Internal.Data.Fold.Type as FL
184+import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
182185
183186import Prelude hiding
184187 (any, all, take, takeWhile, sequence, concatMap, maybe, either, span)
@@ -893,6 +896,7 @@ groupByRollingEither
893896
894897-- XXX use an Unfold instead of a list?
895898-- XXX custom combinators for matching list, array and stream?
899+-- XXX rename to listBy?
896900--
897901-- | See 'Streamly.Internal.Data.Parser.eqBy'.
898902--
@@ -904,6 +908,7 @@ eqBy cmp str = Parser step initial extract
904908
905909 where
906910
911+ -- XXX Should return IDone in initial for [] case
907912 initial = return $ IPartial str
908913
909914 step [] _ = return $ Done 0 ()
@@ -926,6 +931,45 @@ eqBy cmp str = Parser step initial extract
926931 $ "eqBy: end of input, yet to match "
927932 ++ show (length xs) ++ " elements"
928933
934+-- XXX rename to streamBy?
935+-- | Like eqBy but uses a stream instead of a list
936+{-# INLINE matchBy #-}
937+matchBy :: MonadThrow m => (a -> a -> Bool) -> D.Stream m a -> Parser m a ()
938+matchBy cmp (D.Stream sstep state) = Parser step initial extract
939+
940+ where
941+
942+ initial = do
943+ r <- sstep defState state
944+ case r of
945+ D.Yield x s -> return $ IPartial (Just x, s)
946+ D.Stop -> return $ IDone ()
947+ -- Need Skip/Continue in initial to loop right here
948+ D.Skip s -> return $ IPartial (Nothing, s)
949+
950+ step (Just x, st) a =
951+ if x `cmp` a
952+ then do
953+ r <- sstep defState st
954+ return
955+ $ case r of
956+ D.Yield x1 s -> Continue 0 (Just x1, s)
957+ D.Stop -> Done 0 ()
958+ D.Skip s -> Continue 1 (Nothing, s)
959+ else return $ Error "match: mismtach occurred"
960+ step (Nothing, st) a = do
961+ r <- sstep defState st
962+ return
963+ $ case r of
964+ D.Yield x s -> do
965+ if x `cmp` a
966+ then Continue 0 (Nothing, s)
967+ else Error "match: mismatch occurred"
968+ D.Stop -> Done 1 ()
969+ D.Skip s -> Continue 1 (Nothing, s)
970+
971+ extract _ = throwM $ ParseError "match: end of input"
972+
929973--------------------------------------------------------------------------------
930974--- Spanning
931975--------------------------------------------------------------------------------