on master help sign in
Redo Data.Text.find's type and behaviour

--HG-- extra : convert_revision : 8b8b5bd3bec4b557b80b4d6e858eda11f19cedbe

commitf50288bce4e33304d73188f163c0e2d791a21175 authorBryan O'Sullivan <bos@serpentine.com> dateSat 3 Jul 2010, 01:16 (16 years ago) parentad42860
2 files changed+19−24
Data/Text.hs+14−18 tests/Properties.hs+5−6
Data/Text.hs+14−18
@@ -1086,34 +1086,30 @@ breakEnd pat src = let (a,b) = break (reverse pat) (reverse src)
10861086{-# INLINE breakEnd #-}
10871087
10881088-- | /O(n+m)/ Find all non-overlapping instances of @needle@ in
1089−-- @haystack@. The first element of the returned pair is the prefix
1090−-- of @haystack@ prior to any matches of @needle@. The second is a
1091−-- list of pairs.
1089+-- @haystack@. Each element of the returned list consists of a triple:
10921090--
1093−-- The first element of each pair in the list is a span from the
1094−-- beginning of a match to the beginning of the next match, while the
1095−-- second is a span from the beginning of the match to the end of the
1096−-- input.
1091+-- * The entire string prior to the /k/th match
1092+--
1093+-- * The /k/th match
1094+--
1095+-- * The entire string following the /k/th match
10971096--
10981097-- Examples:
10991098--
11001099-- > find "::" ""
1101−-- > ==> ("", [])
1102−-- > find "/" "a/b/c/d"
1103−-- > ==> ("a", [("/b","/b/c/d"), ("/c","/c/d"), ("/d","/d")])
1100+-- > ==> []
1101+-- > find "/" "a/b/c/"
1102+-- > ==> [("a", "/", "b/c/"), ("a/b", "/", "c/"), ("a/b/c", "/", "")]
11041103--
11051104-- In (unlikely) bad cases, this function's time complexity degrades
11061105-- towards /O(n*m)/.
1107−find :: Text -> Text -> (Text, [(Text, Text)])
1108−find pat src@(Text arr off len)
1106+find :: Text -> Text -> [(Text, Text, Text)]
1107+find pat@(Text _ _ plen) src@(Text arr off slen)
11091108 | null pat = emptyError "find"
1110− | otherwise = case indices pat src of
1111− [] -> (src, [])
1112− (x:xs) -> (chunk 0 x, go x xs)
1109+ | otherwise = L.map step (indices pat src)
11131110 where
1114− go !s (x:xs) = (chunk s (x-s), chunk s (len-s)) : go x xs
1115− go s _ = let c = chunk s (len-s)
1116− in [(c,c)]
1111+ step x = (chunk 0 x, chunk x plen, chunk (x+plen) (stop-x))
1112+ stop = slen - plen
11171113 chunk !n !l = textP arr (n+off) l
11181114{-# INLINE find #-}
11191115
tests/Properties.hs+5−6
@@ -408,11 +408,9 @@ t_inits = L.inits `eqP` (map unpackS . T.inits)
408408tl_inits = L.inits `eqP` (map unpackS . TL.inits)
409409t_tails = L.tails `eqP` (map unpackS . T.tails)
410410tl_tails = L.tails `eqP` (map unpackS . TL.tails)
411−
412−t_findSplit s t = (T.split s `eq` splitty) u
413− where splitty v = case T.find s v of
414− (x,xs) -> x : L.map (T.drop (T.length s) . fst) xs
415− u = T.concat [t,s,t]
411+t_findConcat (NotEmpty s) t = all (==t) $ map conc (T.find s t)
412+ where conc (a,b,c) = T.concat [a,b,c]
413+t_findCount s = (L.length . T.find s) `eq` T.count s
416414tl_findSplit s t = (TL.split s `eq` splitty) u
417415 where splitty v = case TL.find s v of
418416 (x,xs) -> x : L.map (TL.drop (TL.length s) . fst) xs
@@ -812,7 +810,8 @@ tests = [
812810 ],
813811
814812 testGroup "breaking many" [
815− testProperty "t_findSplit" t_findSplit,
813+ testProperty "t_findConcat" t_findConcat,
814+ testProperty "t_findCount" t_findCount,
816815 testProperty "tl_findSplit" tl_findSplit,
817816 testProperty "t_split_split" t_split_split,
818817 testProperty "tl_split_split" tl_split_split,