@@ -1034,13 +1034,23 @@ isSuffixOf x y = reverse x `isPrefixOf` reverse y
1034{-# INLINE isSuffixOf #-}
1034{-# INLINE isSuffixOf #-}
1035-- TODO: a better implementation
1035-- TODO: a better implementation
1037−-- | /O(n)/ The 'isInfixOf' function takes two 'Text's and returns
1037+-- | /O(n+m)/ The 'isInfixOf' function takes two 'Text's and returns
1038-- 'True' iff the first is contained, wholly and intact, anywhere
1038-- 'True' iff the first is contained, wholly and intact, anywhere
1039-- within the second.
1039-- within the second.
1041+-- In (unlikely) bad cases, this function's time complexity degrades
1042+-- towards /O(n*m)/.
1040isInfixOf :: Text -> Text -> Bool
1043isInfixOf :: Text -> Text -> Bool
1041−isInfixOf needle haystack = L.any (isPrefixOf needle) (tails haystack)
1044+isInfixOf needle haystack
1045+ | null needle = True
1046+ | isSingleton needle = S.elem (head needle) . S.stream $ haystack
1047+ | otherwise = not . L.null . indices needle $ haystack
1042−{-# INLINE isInfixOf #-}
1048+{-# INLINE [1] isInfixOf #-}
1043−-- TODO: a better implementation
1049+
1051+"LAZY TEXT isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1052+ isInfixOf (singleton n) h = S.elem n (S.stream h)
1045-- | /O(n)/ 'filter', applied to a predicate and a 'Text',
1055-- | /O(n)/ 'filter', applied to a predicate and a 'Text',
1046-- returns a 'Text' containing those characters that satisfy the
1056-- returns a 'Text' containing those characters that satisfy the
@@ -1070,21 +1080,18 @@ index :: Text -> Int64 -> Char
1070index t n = S.index (stream t) n
1080index t n = S.index (stream t) n
1071{-# INLINE index #-}
1081{-# INLINE index #-}
1073−-- | /O(n*m)/ The 'count' function returns the number of times the
1083+-- | /O(n+m)/ The 'count' function returns the number of times the
1074-- query string appears in the given 'Text'. An empty query string is
1084-- query string appears in the given 'Text'. An empty query string is
1075-- invalid, and will cause an error to be raised.
1085-- invalid, and will cause an error to be raised.
1087+-- In (unlikely) bad cases, this function's time complexity degrades
1088+-- towards /O(n*m)/.
1076count :: Text -> Text -> Int64
1089count :: Text -> Text -> Int64
1077−count pat src0
1090+count pat src
1078− | l == 0 = emptyError "count"
1091+ | null pat = emptyError "count"
1079− | l == 1 = countChar (head pat) src0
1092+ | otherwise = len (indices pat src)
1080− | otherwise = go 0 src0
1081− where
1093+ where len [] = 0
1082− l = length pat
1094+ len (_:xs) = 1 + len xs
1083− go !n src = search src
1085− search s | null s = n
1086− | pat `isPrefixOf` s = go (n+1) (drop l s)
1087− | otherwise = search (tail s)
1088{-# INLINE [1] count #-}
1095{-# INLINE [1] count #-}
1090{-# RULES
1097{-# RULES