on master help sign in
Replace isPrefix implementation with streamed version

--HG-- extra : convert_revision : bc2a647211a4d913f7e12b97faa2c944cb56ac2e

commitaa778400dc674cd64baddd189298ad2d265a82e1 authorBryan O'Sullivan <bos@serpentine.com> dateThu 12 Feb 2009, 07:10 (18 years ago) parent26830b5
3 files changed+28−6
Data/Text.hs+9−6 Data/Text/Fusion.hs+17 tests/Properties.hs+2
Data/Text.hs+9−6
@@ -837,13 +837,16 @@ unwords = intercalate (singleton ' ')
837837{-# INLINE unwords #-}
838838
839839isPrefixOf :: Text -> Text -> Bool
840−isPrefixOf a@(Text _ _ alen) b@(Text _ _ blen) = alen <= blen && loop 0 0
841− where loop !i !j | i >= alen = True
842− | c == e = loop (i+d) (j+f)
843− | otherwise = False
844− where (c,d) = iter a i
845− (e,f) = iter b j
840+isPrefixOf a@(Text _ _ alen) b@(Text _ _ blen) =
841+ alen <= blen && S.isPrefixOf (stream a) (stream b)
846842{-# INLINE [1] isPrefixOf #-}
847843
844+{-# RULES
845+"TEXT isPrefixOf -> fused" [~1] forall s t.
846+ isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
847+"TEXT isPrefixOf -> unfused" [1] forall s t.
848+ S.isPrefixOf (stream s) (stream t) = isPrefixOf s t
849+ #-}
850+
848851errorEmptyList :: String -> a
849852errorEmptyList fun = error ("Data.Text." ++ fun ++ ": empty list")
Data/Text/Fusion.hs+17
@@ -79,6 +79,9 @@ module Data.Text.Fusion
7979 , takeWhile
8080 , dropWhile
8181
82+ -- * Predicates
83+ , isPrefixOf
84+
8285 -- * Searching
8386 , elem
8487 , filter
@@ -683,6 +686,19 @@ dropWhile p (Stream next0 s0 len) = Stream next (S1 :!: s0) len
683686 Yield x s' -> Yield x (S2 :!: s')
684687{-# INLINE [0] dropWhile #-}
685688
689+isPrefixOf :: (Eq a) => Stream a -> Stream a -> Bool
690+isPrefixOf (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)
691+ where
692+ loop Done _ = True
693+ loop _ Done = False
694+ loop (Skip s1') (Skip s2') = loop (next1 s1') (next2 s2')
695+ loop (Skip s1') x2 = loop (next1 s1') x2
696+ loop x1 (Skip s2') = loop x1 (next2 s2')
697+ loop (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&
698+ loop (next1 s1') (next2 s2')
699+{-# INLINE [0] isPrefixOf #-}
700+{-# SPECIALISE isPrefixOf :: Stream Char -> Stream Char -> Bool #-}
701+
686702-- ----------------------------------------------------------------------------
687703-- * Searching
688704
@@ -811,5 +827,6 @@ zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!:
811827 Yield b sb' -> Yield (f a b) (sa' :!: sb' :!: Nothing)
812828{-# INLINE [0] zipWith #-}
813829
830+
814831errorEmptyList :: String -> a
815832errorEmptyList fun = error ("Data.Text.Fusion." ++ fun ++ ": empty list")
tests/Properties.hs+2
@@ -141,6 +141,7 @@ prop_unlines = L.unlines `eq` (unpack . T.unlines . map pack)
141141prop_unwords = L.unwords `eq` (unpack . T.unwords . map pack)
142142
143143prop_isPrefixOf s = L.isPrefixOf s`eqP` T.isPrefixOf (pack s)
144+prop_isPrefixOfS s = L.isPrefixOf s`eqP` (S.isPrefixOf (stream $ pack s) . stream)
144145
145146prop_elem c = L.elem c `eqP` T.elem c
146147prop_filter p = L.filter p `eqP` (unpack . T.filter p)
@@ -238,6 +239,7 @@ tests = [
238239 ("prop_unwords", mytest prop_unwords),
239240
240241 ("prop_isPrefixOf", mytest prop_isPrefixOf),
242+ ("prop_isPrefixOfS", mytest prop_isPrefixOfS),
241243
242244 ("prop_elem", mytest prop_elem),
243245 ("prop_filter", mytest prop_filter),