on master help sign in
Implement and test lazy isPrefixOf
1f4aef2Bryan O'Sullivan
Data/Text/Lazy.hs+24−1
@@ -120,7 +120,7 @@ module Data.Text.Lazy
120 , unwords
120 , unwords
121
121
122 -- * Predicates
122 -- * Predicates
123− -- , isPrefixOf
123+ , isPrefixOf
124 -- , isSuffixOf
124 -- , isSuffixOf
125 -- , isInfixOf
125 -- , isInfixOf
126
126
@@ -743,6 +743,29 @@ unwords :: [Text] -> Text
743unwords = intercalate (singleton ' ')
743unwords = intercalate (singleton ' ')
744{-# INLINE unwords #-}
744{-# INLINE unwords #-}
745
745
746+-- | /O(n)/ The 'isPrefixOf' function takes two 'Text's and returns
747+-- 'True' iff the first is a prefix of the second. This function is
748+-- subject to fusion.
749+isPrefixOf :: Text -> Text -> Bool
750+isPrefixOf Empty _ = True
751+isPrefixOf _ Empty = False
752+isPrefixOf (Chunk x xs) (Chunk y ys)
753+ | lx == ly = x == y && isPrefixOf xs ys
754+ | lx < ly = x == yh && isPrefixOf xs (Chunk yt ys)
755+ | otherwise = xh == y && isPrefixOf (Chunk xt xs) ys
756+ where (xh,xt) = T.splitAt ly x
757+ (yh,yt) = T.splitAt lx y
758+ lx = T.length x
759+ ly = T.length y
760+{-# INLINE [1] isPrefixOf #-}
761+
762+{-# RULES
763+"LAZY TEXT isPrefixOf -> fused" [~1] forall s t.
764+ isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
765+"LAZY TEXT isPrefixOf -> unfused" [1] forall s t.
766+ S.isPrefixOf (stream s) (stream t) = isPrefixOf s t
767+ #-}
768+
746revChunks :: [T.Text] -> Text
769revChunks :: [T.Text] -> Text
747revChunks = L.foldl' (flip chunk) Empty
770revChunks = L.foldl' (flip chunk) Empty
748
771
tests/Properties.hs+4−2
@@ -300,8 +300,9 @@ prop_TL_unlines = L.unlines `eq` (unpackT . TL.unlines . map packT)
300prop_T_unwords = L.unwords `eq` (unpackT . T.unwords . map packT)
300prop_T_unwords = L.unwords `eq` (unpackT . T.unwords . map packT)
301prop_TL_unwords = L.unwords `eq` (unpackT . TL.unwords . map packT)
301prop_TL_unwords = L.unwords `eq` (unpackT . TL.unwords . map packT)
302
302
303+prop_S_isPrefixOf s = L.isPrefixOf s`eqP` (S.isPrefixOf (S.stream $ packT s) . S.stream)
303prop_T_isPrefixOf s = L.isPrefixOf s`eqP` T.isPrefixOf (packT s)
304prop_T_isPrefixOf s = L.isPrefixOf s`eqP` T.isPrefixOf (packT s)
304−prop_T_isPrefixOfS s = L.isPrefixOf s`eqP` (S.isPrefixOf (S.stream $ packT s) . S.stream)
305+prop_TL_isPrefixOf s = L.isPrefixOf s`eqP` TL.isPrefixOf (packT s)
305prop_T_isSuffixOf s = L.isSuffixOf s`eqP` T.isSuffixOf (packT s)
306prop_T_isSuffixOf s = L.isSuffixOf s`eqP` T.isSuffixOf (packT s)
306prop_T_isInfixOf s = L.isInfixOf s `eqP` T.isInfixOf (packT s)
307prop_T_isInfixOf s = L.isInfixOf s `eqP` T.isInfixOf (packT s)
307
308
@@ -496,8 +497,9 @@ tests = [
496 ("prop_TL_unlines", mytest prop_TL_unlines),
497 ("prop_TL_unlines", mytest prop_TL_unlines),
497 ("prop_TL_unwords", mytest prop_TL_unwords),
498 ("prop_TL_unwords", mytest prop_TL_unwords),
498
499
500+ ("prop_S_isPrefixOf", mytest prop_S_isPrefixOf),
499 ("prop_T_isPrefixOf", mytest prop_T_isPrefixOf),
501 ("prop_T_isPrefixOf", mytest prop_T_isPrefixOf),
500− ("prop_T_isPrefixOfS", mytest prop_T_isPrefixOfS),
502+ ("prop_TL_isPrefixOf", mytest prop_TL_isPrefixOf),
501 ("prop_T_isSuffixOf", mytest prop_T_isSuffixOf),
503 ("prop_T_isSuffixOf", mytest prop_T_isSuffixOf),
502 ("prop_T_isInfixOf", mytest prop_T_isInfixOf),
504 ("prop_T_isInfixOf", mytest prop_T_isInfixOf),
503
505