@@ -140,6 +140,10 @@ module Data.Text
140 , isSuffixOf
140 , isSuffixOf
141 , isInfixOf
141 , isInfixOf
143 -- * Searching
147 -- * Searching
@@ -165,7 +169,7 @@ module Data.Text
165import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
169import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
166 Eq(..), Ord(..), (++),
170 Eq(..), Ord(..), (++),
167 Read(..), Show(..),
171 Read(..), Show(..),
168− (&&), (||), (+), (-), (.), ($), (>>), (*),
172+ (&&), (||), (+), (-), (.), ($), ($!), (>>), (*),
169 div, error, not, return, otherwise)
173 div, error, not, return, otherwise)
170#if defined(HAVE_DEEPSEQ)
174#if defined(HAVE_DEEPSEQ)
171import Control.DeepSeq (NFData)
175import Control.DeepSeq (NFData)
@@ -1289,5 +1293,52 @@ isInfixOf needle haystack
1289 isInfixOf (singleton n) h = S.elem n (S.stream h)
1293 isInfixOf (singleton n) h = S.elem n (S.stream h)
1296+-------------------------------------------------------------------------------
1299+-- | /O(n)/ Returns the suffix of the second string if its prefix
1300+-- matches the first.
1304+-- > prefixed "foo" "foobar" == Just "bar"
1305+-- > prefixed "foo" "quux" == Nothing
1307+-- This is particularly useful with the @ViewPatterns@ extension to
1310+-- > {-# LANGUAGE ViewPatterns #-}
1311+-- > import Data.Text as T
1313+-- > fnordLength :: Text -> Int
1314+-- > fnordLength (prefixed "fnord" -> Just suf) = T.length suf
1315+-- > fnordLength _ = -1
1316+prefixed :: Text -> Text -> Maybe Text
1317+prefixed p@(Text _arr _off plen) t@(Text arr off len)
1318+ | p `isPrefixOf` t = Just $! textP arr (off+plen) (len-plen)
1319+ | otherwise = Nothing
1321+-- | /O(n)/ Returns the prefix of the second string if its suffix
1322+-- matches the first.
1326+-- > suffixed "bar" "foobar" == Just "foo"
1327+-- > suffixed "foo" "quux" == Nothing
1329+-- This is particularly useful with the @ViewPatterns@ extension to
1332+-- > {-# LANGUAGE ViewPatterns #-}
1333+-- > import Data.Text as T
1335+-- > quuxLength :: Text -> Int
1336+-- > quuxLength (suffixed "quux" -> Just pre) = T.length pre
1337+-- > quuxLength _ = -1
1338+suffixed :: Text -> Text -> Maybe Text
1339+suffixed p@(Text _arr _off plen) t@(Text arr off len)
1340+ | p `isSuffixOf` t = Just $! textP arr off (len-plen)
1341+ | otherwise = Nothing
1292emptyError :: String -> a
1343emptyError :: String -> a
1293emptyError fun = P.error ("Data.Text." ++ fun ++ ": empty input")
1344emptyError fun = P.error ("Data.Text." ++ fun ++ ": empty input")