Bryan O'Sullivan avatar Bryan O'Sullivan committed bc0b974

Implement and test lazy isPrefixOf

Comments (0)

Files changed (2)

Data/Text/Lazy.hs

     , unwords
 
     -- * Predicates
-    -- , isPrefixOf
+    , isPrefixOf
     -- , isSuffixOf
     -- , isInfixOf
 
 unwords = intercalate (singleton ' ')
 {-# INLINE unwords #-}
 
+-- | /O(n)/ The 'isPrefixOf' function takes two 'Text's and returns
+-- 'True' iff the first is a prefix of the second.  This function is
+-- subject to fusion.
+isPrefixOf :: Text -> Text -> Bool
+isPrefixOf Empty _  = True
+isPrefixOf _ Empty  = False
+isPrefixOf (Chunk x xs) (Chunk y ys)
+    | lx == ly  = x == y  && isPrefixOf xs ys
+    | lx <  ly  = x == yh && isPrefixOf xs (Chunk yt ys)
+    | otherwise = xh == y && isPrefixOf (Chunk xt xs) ys
+  where (xh,xt) = T.splitAt ly x
+        (yh,yt) = T.splitAt lx y
+        lx = T.length x
+        ly = T.length y
+{-# INLINE [1] isPrefixOf #-}
+
+{-# RULES
+"LAZY TEXT isPrefixOf -> fused" [~1] forall s t.
+    isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
+"LAZY TEXT isPrefixOf -> unfused" [1] forall s t.
+    S.isPrefixOf (stream s) (stream t) = isPrefixOf s t
+  #-}
+
 revChunks :: [T.Text] -> Text
 revChunks = L.foldl' (flip chunk) Empty
 

tests/Properties.hs

 prop_T_unwords         = L.unwords     `eq`  (unpackT . T.unwords . map packT)
 prop_TL_unwords        = L.unwords     `eq`  (unpackT . TL.unwords . map packT)
 
+prop_S_isPrefixOf s    = L.isPrefixOf s`eqP` (S.isPrefixOf (S.stream $ packT s) . S.stream)
 prop_T_isPrefixOf s    = L.isPrefixOf s`eqP` T.isPrefixOf (packT s)
-prop_T_isPrefixOfS s   = L.isPrefixOf s`eqP` (S.isPrefixOf (S.stream $ packT s) . S.stream)
+prop_TL_isPrefixOf s   = L.isPrefixOf s`eqP` TL.isPrefixOf (packT s)
 prop_T_isSuffixOf s    = L.isSuffixOf s`eqP` T.isSuffixOf (packT s)
 prop_T_isInfixOf s     = L.isInfixOf s `eqP` T.isInfixOf (packT s)
 
   ("prop_TL_unlines", mytest prop_TL_unlines),
   ("prop_TL_unwords", mytest prop_TL_unwords),
 
+  ("prop_S_isPrefixOf", mytest prop_S_isPrefixOf),
   ("prop_T_isPrefixOf", mytest prop_T_isPrefixOf),
-  ("prop_T_isPrefixOfS", mytest prop_T_isPrefixOfS),
+  ("prop_TL_isPrefixOf", mytest prop_TL_isPrefixOf),
   ("prop_T_isSuffixOf", mytest prop_T_isSuffixOf),
   ("prop_T_isInfixOf", mytest prop_T_isInfixOf),
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.