on master help sign in
Add a stream equality match parser
5dbf2acHarendra Kumar
core/src/Streamly/Internal/Data/Parser/ParserD.hs+44
@@ -77,6 +77,7 @@ module Streamly.Internal.Data.Parser.ParserD
77 , groupByRolling
77 , groupByRolling
78 , groupByRollingEither
78 , groupByRollingEither
79 , eqBy
79 , eqBy
80+ , matchBy
80 -- , prefixOf -- match any prefix of a given string
81 -- , prefixOf -- match any prefix of a given string
81 -- , suffixOf -- match any suffix of a given string
82 -- , suffixOf -- match any suffix of a given string
82 -- , infixOf -- match any substring of a given string
83 -- , infixOf -- match any substring of a given string
@@ -176,9 +177,11 @@ import Control.Monad (when)
176import Control.Monad.Catch (MonadCatch, MonadThrow(..))
177import Control.Monad.Catch (MonadCatch, MonadThrow(..))
177import Fusion.Plugin.Types (Fuse(..))
178import Fusion.Plugin.Types (Fuse(..))
178import Streamly.Internal.Data.Fold.Type (Fold(..))
179import Streamly.Internal.Data.Fold.Type (Fold(..))
180+import Streamly.Internal.Data.SVar.Type (defState)
179import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
181import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
180
182
181import qualified Streamly.Internal.Data.Fold.Type as FL
183import qualified Streamly.Internal.Data.Fold.Type as FL
184+import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
182
185
183import Prelude hiding
186import Prelude hiding
184 (any, all, take, takeWhile, sequence, concatMap, maybe, either, span)
187 (any, all, take, takeWhile, sequence, concatMap, maybe, either, span)
@@ -893,6 +896,7 @@ groupByRollingEither
893
896
894-- XXX use an Unfold instead of a list?
897-- XXX use an Unfold instead of a list?
895-- XXX custom combinators for matching list, array and stream?
898-- XXX custom combinators for matching list, array and stream?
899+-- XXX rename to listBy?
896--
900--
897-- | See 'Streamly.Internal.Data.Parser.eqBy'.
901-- | See 'Streamly.Internal.Data.Parser.eqBy'.
898--
902--
@@ -904,6 +908,7 @@ eqBy cmp str = Parser step initial extract
904
908
905 where
909 where
906
910
911+ -- XXX Should return IDone in initial for [] case
907 initial = return $ IPartial str
912 initial = return $ IPartial str
908
913
909 step [] _ = return $ Done 0 ()
914 step [] _ = return $ Done 0 ()
@@ -926,6 +931,45 @@ eqBy cmp str = Parser step initial extract
926 $ "eqBy: end of input, yet to match "
931 $ "eqBy: end of input, yet to match "
927 ++ show (length xs) ++ " elements"
932 ++ show (length xs) ++ " elements"
928
933
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+
929--------------------------------------------------------------------------------
973--------------------------------------------------------------------------------
930--- Spanning
974--- Spanning
931--------------------------------------------------------------------------------
975--------------------------------------------------------------------------------