text 0.11.0.0 → 0.11.0.1
raw patch · 4 files changed
+99/−24 lines, 4 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Data.Text: commonPrefixes :: Text -> Text -> Maybe (Text, Text, Text)
+ Data.Text.Lazy: commonPrefixes :: Text -> Text -> Maybe (Text, Text, Text)
Files
- Data/Text.hs +32/−6
- Data/Text/Lazy.hs +43/−16
- tests/Properties.hs +23/−1
- text.cabal +1/−1
Data/Text.hs view
@@ -158,6 +158,7 @@ -- ** View patterns , stripPrefix , stripSuffix+ , commonPrefixes -- * Searching , filter@@ -1473,12 +1474,13 @@ ------------------------------------------------------------------------------- -- * View patterns --- | /O(n)/ Returns the suffix of the second string if its prefix--- matches the first.+-- | /O(n)/ Return the suffix of the second string if its prefix+-- matches the entire first string. -- -- Examples: -- -- > stripPrefix "foo" "foobar" == Just "bar"+-- > stripPrefix "" "baz" == Just "baz" -- > stripPrefix "foo" "quux" == Nothing -- -- This is particularly useful with the @ViewPatterns@ extension to@@ -1489,18 +1491,42 @@ -- > -- > fnordLength :: Text -> Int -- > fnordLength (stripPrefix "fnord" -> Just suf) = T.length suf--- > fnordLength _ = -1+-- > fnordLength _ = -1 stripPrefix :: Text -> Text -> Maybe Text stripPrefix p@(Text _arr _off plen) t@(Text arr off len) | p `isPrefixOf` t = Just $! textP arr (off+plen) (len-plen) | otherwise = Nothing --- | /O(n)/ Returns the prefix of the second string if its suffix--- matches the first.+-- | /O(n)/ Find the longest non-empty common prefix of two strings+-- and return it, along with the suffixes of each string at which they+-- no longer match. --+-- If the strings do not have a common prefix or either one is empty,+-- this function returns 'Nothing'.+-- -- Examples: --+-- > commonPrefixes "foobar" "fooquux" == Just ("foo","bar","quux")+-- > commonPrefixes "veeble" "fetzer" == Nothing+-- > commonPrefixes "" "baz" == Nothing+commonPrefixes :: Text -> Text -> Maybe (Text,Text,Text)+commonPrefixes t0@(Text arr0 off0 len0) t1@(Text arr1 off1 len1) = go 0 0+ where+ go !i !j | i < len0 && j < len1 && a == b = go (i+d0) (j+d1)+ | i > 0 = Just (Text arr0 off0 i,+ textP arr0 (off0+i) (len0-i),+ textP arr1 (off1+j) (len1-j))+ | otherwise = Nothing+ where Iter a d0 = iter t0 i+ Iter b d1 = iter t1 j++-- | /O(n)/ Return the prefix of the second string if its suffix+-- matches the entire first string.+--+-- Examples:+-- -- > stripSuffix "bar" "foobar" == Just "foo"+-- > stripSuffix "" "baz" == Just "baz" -- > stripSuffix "foo" "quux" == Nothing -- -- This is particularly useful with the @ViewPatterns@ extension to@@ -1511,7 +1537,7 @@ -- > -- > quuxLength :: Text -> Int -- > quuxLength (stripSuffix "quux" -> Just pre) = T.length pre--- > quuxLength _ = -1+-- > quuxLength _ = -1 stripSuffix :: Text -> Text -> Maybe Text stripSuffix p@(Text _arr _off plen) t@(Text arr off len) | p `isSuffixOf` t = Just $! textP arr off (len-plen)
Data/Text/Lazy.hs view
@@ -165,6 +165,7 @@ -- ** View patterns , stripPrefix , stripSuffix+ , commonPrefixes -- * Searching , filter@@ -189,7 +190,7 @@ import Prelude (Char, Bool(..), Maybe(..), String, Eq(..), Ord(..), Ordering(..), Read(..), Show(..), (&&), (||), (+), (-), (.), ($), (++),- div, error, flip, fromIntegral, not, otherwise)+ div, error, flip, fmap, fromIntegral, not, otherwise) import qualified Prelude as P #if defined(HAVE_DEEPSEQ) import Control.DeepSeq (NFData(..))@@ -1325,51 +1326,77 @@ ------------------------------------------------------------------------------- -- * View patterns --- | /O(n)/ Returns the suffix of the second string if its prefix--- matches the first.+-- | /O(n)/ Return the suffix of the second string if its prefix+-- matches the entire first string. -- -- Examples: -- -- > stripPrefix "foo" "foobar" == Just "bar"+-- > stripPrefix "" "baz" == Just "baz" -- > stripPrefix "foo" "quux" == Nothing -- -- This is particularly useful with the @ViewPatterns@ extension to -- GHC, as follows: -- -- > {-# LANGUAGE ViewPatterns #-}--- > import Data.Text as T+-- > import Data.Text.Lazy as T -- > -- > fnordLength :: Text -> Int -- > fnordLength (stripPrefix "fnord" -> Just suf) = T.length suf--- > fnordLength _ = -1+-- > fnordLength _ = -1 stripPrefix :: Text -> Text -> Maybe Text--- Yes, this could be much more efficient. stripPrefix p t- | p `isPrefixOf` t = Just (drop (length p) t)- | otherwise = Nothing+ | null p = Just t+ | otherwise = case commonPrefixes p t of+ Just (_,c,r) | null c -> Just r+ _ -> Nothing --- | /O(n)/ Returns the prefix of the second string if its suffix--- matches the first.+-- | /O(n)/ Find the longest non-empty common prefix of two strings+-- and return it, along with the suffixes of each string at which they+-- no longer match. --+-- If the strings do not have a common prefix or either one is empty,+-- this function returns 'Nothing'.+-- -- Examples: --+-- > commonPrefixes "foobar" "fooquux" == Just ("foo","bar","quux")+-- > commonPrefixes "veeble" "fetzer" == Nothing+-- > commonPrefixes "" "baz" == Nothing+commonPrefixes :: Text -> Text -> Maybe (Text,Text,Text)+commonPrefixes Empty _ = Nothing+commonPrefixes _ Empty = Nothing+commonPrefixes a0 b0 = Just (go a0 b0 [])+ where+ go t0@(Chunk x xs) t1@(Chunk y ys) ps+ = case T.commonPrefixes x y of+ Just (p,a,b)+ | T.null a -> go xs (chunk b ys) (p:ps)+ | T.null b -> go (chunk a xs) ys (p:ps)+ | otherwise -> (fromChunks (L.reverse (p:ps)),chunk a xs, chunk b ys)+ Nothing -> (fromChunks (L.reverse ps),t0,t1)+ go t0 t1 ps = (fromChunks (L.reverse ps),t0,t1)++-- | /O(n)/ Return the prefix of the second string if its suffix+-- matches the entire first string.+--+-- Examples:+-- -- > stripSuffix "bar" "foobar" == Just "foo"+-- > stripSuffix "" "baz" == Just "baz" -- > stripSuffix "foo" "quux" == Nothing -- -- This is particularly useful with the @ViewPatterns@ extension to -- GHC, as follows: -- -- > {-# LANGUAGE ViewPatterns #-}--- > import Data.Text as T+-- > import Data.Text.Lazy as T -- > -- > quuxLength :: Text -> Int -- > quuxLength (stripSuffix "quux" -> Just pre) = T.length pre--- > quuxLength _ = -1+-- > quuxLength _ = -1 stripSuffix :: Text -> Text -> Maybe Text--- Yes, this could be much more efficient.-stripSuffix p t- | p `isSuffixOf` t = Just (take (length t - length p) t)- | otherwise = Nothing+stripSuffix p t = reverse `fmap` stripPrefix (reverse p) (reverse t) -- | /O(n)/ 'filter', applied to a predicate and a 'Text', -- returns a 'Text' containing those characters that satisfy the
tests/Properties.hs view
@@ -591,6 +591,26 @@ t_stripSuffix s = (fmap packS . stripSuffix s) `eqP` T.stripSuffix (packS s) tl_stripSuffix s = (fmap packS . stripSuffix s) `eqP` TL.stripSuffix (packS s) +commonPrefixes a0@(_:_) b0@(_:_) = Just (go a0 b0 [])+ where go (a:as) (b:bs) ps+ | a == b = go as bs (a:ps)+ go as bs ps = (reverse ps,as,bs)+commonPrefixes _ _ = Nothing++t_commonPrefixes a b (NonEmpty p)+ = commonPrefixes pa pb ==+ repack `fmap` T.commonPrefixes (packS pa) (packS pb)+ where repack (x,y,z) = (unpackS x,unpackS y,unpackS z)+ pa = p ++ a+ pb = p ++ b++tl_commonPrefixes a b (NonEmpty p)+ = commonPrefixes pa pb ==+ repack `fmap` TL.commonPrefixes (packS pa) (packS pb)+ where repack (x,y,z) = (unpackS x,unpackS y,unpackS z)+ pa = p ++ a+ pb = p ++ b+ sf_elem p c = (L.elem c . L.filter p) `eqP` (S.elem c . S.filter p) sf_filter q p = (L.filter p . L.filter q) `eqP` (unpackS . S.filter p . S.filter q)@@ -1120,7 +1140,9 @@ testProperty "t_stripPrefix" t_stripPrefix, testProperty "tl_stripPrefix" tl_stripPrefix, testProperty "t_stripSuffix" t_stripSuffix,- testProperty "tl_stripSuffix" tl_stripSuffix+ testProperty "tl_stripSuffix" tl_stripSuffix,+ testProperty "t_commonPrefixes" t_commonPrefixes,+ testProperty "tl_commonPrefixes" tl_commonPrefixes ] ],
text.cabal view
@@ -1,5 +1,5 @@ name: text-version: 0.11.0.0+version: 0.11.0.1 homepage: http://bitbucket.org/bos/text bug-reports: http://bitbucket.org/bos/text/issues synopsis: An efficient packed Unicode text type.