@@ -3,6 +3,9 @@
3#if __GLASGOW_HASKELL__ >= 702
3#if __GLASGOW_HASKELL__ >= 702
4{-# LANGUAGE Trustworthy #-}
4{-# LANGUAGE Trustworthy #-}
6+#if __GLASGOW_HASKELL__ >= 708
7+{-# LANGUAGE TypeFamilies #-}
8-- Module : Data.Text
11-- Module : Data.Text
@@ -29,8 +32,8 @@
30-- To use an extended and very rich family of functions for working
33-- To use an extended and very rich family of functions for working
31-- with Unicode text (including normalization, regular expressions,
34-- with Unicode text (including normalization, regular expressions,
32−-- non-standard encodings, text breaking, and locales), see the
35+-- non-standard encodings, text breaking, and locales), see
33−-- @text-icu@ package: <http://hackage.haskell.org/package/text-icu>
36+-- <http://hackage.haskell.org/package/text-icu the text-icu package >.
35module Data.Text
38module Data.Text
@@ -126,6 +129,7 @@ module Data.Text
127 , dropEnd
130 , dropEnd
128 , takeWhile
131 , takeWhile
129 , dropWhile
133 , dropWhile
130 , dropWhileEnd
134 , dropWhileEnd
131 , dropAround
135 , dropAround
@@ -188,15 +192,16 @@ module Data.Text
189 -- * Low level operations
193 -- * Low level operations
193import Prelude (Char, Bool(..), Int, Maybe(..), String,
198import Prelude (Char, Bool(..), Int, Maybe(..), String,
194 Eq(..), Ord(..), Ordering(..), (++),
199 Eq(..), Ord(..), Ordering(..), (++),
195− Read(..), Show(..),
200+ Read(..),
196− (&&), (||), (+), (-), (.), ($), ($!), (>>), (*),
201+ (&&), (||), (+), (-), (.), ($), ($!), (>>),
197− maxBound, not, return, otherwise, quot)
202+ not, return, otherwise, quot)
198#if defined(HAVE_DEEPSEQ)
203#if defined(HAVE_DEEPSEQ)
199−import Control.DeepSeq (NFData)
204+import Control.DeepSeq (NFData(rnf))
201#if defined(ASSERTS)
206#if defined(ASSERTS)
202import Control.Exception (assert)
207import Control.Exception (assert)
@@ -205,15 +210,22 @@ import Data.Char (isSpace)
205import Data.Data (Data(gfoldl, toConstr, gunfold, dataTypeOf), constrIndex,
210import Data.Data (Data(gfoldl, toConstr, gunfold, dataTypeOf), constrIndex,
206 Constr, mkConstr, DataType, mkDataType, Fixity(Prefix))
211 Constr, mkConstr, DataType, mkDataType, Fixity(Prefix))
207import Control.Monad (foldM)
212import Control.Monad (foldM)
213+import Control.Monad.ST (ST)
208import qualified Data.Text.Array as A
214import qualified Data.Text.Array as A
209import qualified Data.List as L
215import qualified Data.List as L
216+import Data.Binary (Binary(get, put))
210import Data.Monoid (Monoid(..))
217import Data.Monoid (Monoid(..))
218+#if MIN_VERSION_base(4,9,0)
219+import Data.Semigroup (Semigroup(..))
211import Data.String (IsString(..))
221import Data.String (IsString(..))
212import qualified Data.Text.Internal.Fusion as S
222import qualified Data.Text.Internal.Fusion as S
213import qualified Data.Text.Internal.Fusion.Common as S
223import qualified Data.Text.Internal.Fusion.Common as S
224+import Data.Text.Encoding (decodeUtf8', encodeUtf8)
214import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
225import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
215import Data.Text.Internal.Private (span_)
226import Data.Text.Internal.Private (span_)
216−import Data.Text.Internal (Text(..), empty, firstf, safe, text)
227+import Data.Text.Internal (Text(..), empty, firstf, mul, safe, text)
228+import Data.Text.Show (singleton, unpack, unpackCString#)
217import qualified Prelude as P
229import qualified Prelude as P
218import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
230import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
219 reverseIter_, unsafeHead, unsafeTail)
231 reverseIter_, unsafeHead, unsafeTail)
@@ -226,12 +238,13 @@ import Data.ByteString (ByteString)
226import qualified Data.Text.Lazy as L
238import qualified Data.Text.Lazy as L
227import Data.Int (Int64)
239import Data.Int (Int64)
241+import GHC.Base (eqInt, neInt, gtInt, geInt, ltInt, leInt)
229−#if __GLASGOW_HASKELL__ >= 702
242+#if __GLASGOW_HASKELL__ >= 708
230−import qualified GHC.CString as GHC
243+import qualified GHC.Exts as Exts
232−import qualified GHC.Base as GHC
245+#if MIN_VERSION_base(4,7,0)
246+import Text.Printf (PrintfArg, formatArg, formatString)
234−import GHC.Prim (Addr#)
236-- $strict
249-- $strict
@@ -241,29 +254,32 @@ import GHC.Prim (Addr#)
241-- lazy @Text@ type consists of a list of strict chunks.
254-- lazy @Text@ type consists of a list of strict chunks.
243-- The strict 'Text' type requires that an entire string fit into
256-- The strict 'Text' type requires that an entire string fit into
244−-- memory at once. The lazy @Text@ type is capable of streaming
257+-- memory at once. The lazy 'Data.Text.Lazy.Text' type is capable of
245−-- strings that are larger than memory using a small memory footprint.
258+-- streaming strings that are larger than memory using a small memory
246−-- In many cases, the overhead of chunked streaming makes the lazy
259+-- footprint. In many cases, the overhead of chunked streaming makes
247−-- @Text@ type slower than its strict counterpart, but this is not
260+-- the lazy 'Data.Text.Lazy.Text' type slower than its strict
248−-- always the case. Sometimes, the time complexity of a function in
261+-- counterpart, but this is not always the case. Sometimes, the time
249−-- one module may be different from the other, due to their differing
262+-- complexity of a function in one module may be different from the
250−-- internal structures.
263+-- other, due to their differing internal structures.
252-- Each module provides an almost identical API, with the main
265-- Each module provides an almost identical API, with the main
253-- difference being that the strict module uses 'Int' values for
266-- difference being that the strict module uses 'Int' values for
254−-- lengths and counts, while the lazy module uses 'Int64' lengths.
267+-- lengths and counts, while the lazy module uses 'Data.Int.Int64'
256-- $replacement
270-- $replacement
258-- A 'Text' value is a sequence of Unicode scalar values, as defined
272-- A 'Text' value is a sequence of Unicode scalar values, as defined
259−-- in §3.9, definition D76 of the Unicode 5.2 standard:
274+-- <http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#page=35 §3.9, definition D76 of the Unicode 5.2 standard >.
260−-- <http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#page=35>. As
261−-- such, a 'Text' cannot contain values in the range U+D800 to U+DFFF
275+-- As such, a 'Text' cannot contain values in the range U+D800 to
262−-- inclusive. Haskell implementations admit all Unicode code points
276+-- U+DFFF inclusive. Haskell implementations admit all Unicode code
278+-- (<http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#page=13 §3.4, definition D10 >)
263−-- (§3.4, definition D10) as 'Char' values, including code points
279+-- as 'Char' values, including code points from this invalid range.
264−-- from this invalid range. This means that there are some 'Char'
280+-- This means that there are some 'Char' values that are not valid
265−-- values that are not valid Unicode scalar values, and the functions
281+-- Unicode scalar values, and the functions in this module must handle
266−-- in this module must handle those cases.
282+-- those cases.
268-- Within this module, many functions construct a 'Text' from one or
284-- Within this module, many functions construct a 'Text' from one or
269-- more 'Char' values. Those functions will substitute 'Char' values
285-- more 'Char' values. Those functions will substitute 'Char' values
@@ -277,8 +293,8 @@ import GHC.Prim (Addr#)
277-- range U+D800 through U+DFFF are used by UTF-16 to denote surrogate
293-- range U+D800 through U+DFFF are used by UTF-16 to denote surrogate
278-- code points, and so cannot be represented. The functions replace
294-- code points, and so cannot be represented. The functions replace
279-- invalid scalar values, instead of dropping them, as a security
295-- invalid scalar values, instead of dropping them, as a security
280−-- measure. For details, see Unicode Technical Report 36, §3.5:
296+-- measure. For details, see
281−-- <http://unicode.org/reports/tr36/#Deletion_of_Noncharacters>)
297+-- <http://unicode.org/reports/tr36/#Deletion_of_Noncharacters Unicode Technical Report 36, §3.5 >.)
283-- $fusion
299-- $fusion
@@ -296,11 +312,11 @@ import GHC.Prim (Addr#)
296-- > countChars = T.length . T.toUpper . E.decodeUtf8
312-- > countChars = T.length . T.toUpper . E.decodeUtf8
298-- From the type signatures involved, this looks like it should
314-- From the type signatures involved, this looks like it should
299−-- allocate one 'ByteString' value, and two 'Text' values. However,
315+-- allocate one 'Data.ByteString.ByteString' value, and two 'Text'
300−-- when a module is compiled with optimisation enabled under GHC, the
316+-- values. However, when a module is compiled with optimisation
301−-- two intermediate 'Text' values will be optimised away, and the
317+-- enabled under GHC, the two intermediate 'Text' values will be
302−-- function will be compiled down to a single loop over the source
318+-- optimised away, and the function will be compiled down to a single
303−-- 'ByteString'.
319+-- loop over the source 'Data.ByteString.ByteString'.
305-- Functions that can be fused by the compiler are documented with the
321-- Functions that can be fused by the compiler are documented with the
306-- phrase \"Subject to fusion\".
322-- phrase \"Subject to fusion\".
@@ -314,38 +330,62 @@ instance Eq Text where
314instance Ord Text where
330instance Ord Text where
315 compare = compareText
331 compare = compareText
317−instance Show Text where
318− showsPrec p ps r = showsPrec p (unpack ps) r
320instance Read Text where
333instance Read Text where
321 readsPrec p str = [(pack x,y) | (x,y) <- readsPrec p str]
334 readsPrec p str = [(pack x,y) | (x,y) <- readsPrec p str]
336+#if MIN_VERSION_base(4,9,0)
337+-- Semigroup orphan instances for older GHCs are provided by
338+-- 'semigroups` package
340+instance Semigroup Text where
323instance Monoid Text where
344instance Monoid Text where
324 mempty = empty
345 mempty = empty
346+#if MIN_VERSION_base(4,9,0)
347+ mappend = (<>) -- future-proof definition
325 mappend = append
349 mappend = append
326 mconcat = concat
351 mconcat = concat
328instance IsString Text where
353instance IsString Text where
329 fromString = pack
354 fromString = pack
356+#if __GLASGOW_HASKELL__ >= 708
357+instance Exts.IsList Text where
358+ type Item Text = Char
331#if defined(HAVE_DEEPSEQ)
363#if defined(HAVE_DEEPSEQ)
332−instance NFData Text
364+instance NFData Text where rnf !_ = ()
367+instance Binary Text where
368+ put t = put (encodeUtf8 t)
371+ case decodeUtf8' bs of
372+ P.Left exn -> P.fail (P.show exn)
373+ P.Right a -> P.return a
335-- | This instance preserves data abstraction at the cost of inefficiency.
375-- | This instance preserves data abstraction at the cost of inefficiency.
336-- We omit reflection services for the sake of data abstraction.
376-- We omit reflection services for the sake of data abstraction.
338−-- This instance was created by copying the updated behavior of @Data.Set@ and
378+-- This instance was created by copying the updated behavior of
379+-- @"Data.Set".@'Data.Set.Set' and @"Data.Map".@'Data.Map.Map'. If you
339−-- @Data.Map@. If you feel a mistake has been made, please feel free to
380+-- feel a mistake has been made, please feel free to submit
340−-- submit improvements.
381+-- improvements.
342−-- Original discussion is archived here:
344−-- <http://groups.google.com/group/haskell-cafe/browse_thread/thread/b5bbb1b28a7e525d/0639d46852575b93 could we get a Data instance for Data.Text.Text?>
346−-- The followup discussion that changed the behavior of @Data.Set@ and @Data.Map@ is archived here
383+-- The original discussion is archived here:
384+-- <http://groups.google.com/group/haskell-cafe/browse_thread/thread/b5bbb1b28a7e525d/0639d46852575b93 could we get a Data instance for Data.Text.Text? >
386+-- The followup discussion that changed the behavior of 'Data.Set.Set'
387+-- and 'Data.Map.Map' is archived here:
348−-- <http://markmail.org/message/trovdc6zkphyi3cr#query:+page:1+mid:a46der3iacwjcf6n+state:results Proposal: Allow gunfold for Data.Map, ...>
388+-- <http://markmail.org/message/trovdc6zkphyi3cr#query:+page:1+mid:a46der3iacwjcf6n+state:results Proposal: Allow gunfold for Data.Map, ... >
350instance Data Text where
390instance Data Text where
351 gfoldl f z txt = z pack `f` (unpack txt)
391 gfoldl f z txt = z pack `f` (unpack txt)
@@ -355,6 +395,12 @@ instance Data Text where
355 _ -> P.error "gunfold"
395 _ -> P.error "gunfold"
356 dataTypeOf _ = textDataType
396 dataTypeOf _ = textDataType
398+#if MIN_VERSION_base(4,7,0)
399+-- | Only defined for @base-4.7.0.0@ and later
400+instance PrintfArg Text where
401+ formatArg txt = formatString $ unpack txt
358packConstr :: Constr
404packConstr :: Constr
359packConstr = mkConstr textDataType "pack" [] Prefix
405packConstr = mkConstr textDataType "pack" [] Prefix
@@ -384,30 +430,6 @@ pack :: String -> Text
384pack = unstream . S.map safe . S.streamList
430pack = unstream . S.map safe . S.streamList
385{-# INLINE [1] pack #-}
431{-# INLINE [1] pack #-}
387−-- | /O(n)/ Convert a 'Text' into a 'String'. Subject to fusion.
388−unpack :: Text -> String
389−unpack = S.unstreamList . stream
390−{-# INLINE [1] unpack #-}
392−-- | /O(n)/ Convert a literal string into a Text. Subject to fusion.
393−unpackCString# :: Addr# -> Text
394−unpackCString# addr# = unstream (S.streamCString# addr#)
395−{-# NOINLINE unpackCString# #-}
397−{-# RULES "TEXT literal" forall a.
398− unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
399− = unpackCString# a #-}
401−{-# RULES "TEXT literal UTF8" forall a.
402− unstream (S.map safe (S.streamList (GHC.unpackCStringUtf8# a)))
403− = unpackCString# a #-}
405−-- | /O(1)/ Convert a character into a Text. Subject to fusion.
406−-- Performs replacement on invalid scalar values.
407−singleton :: Char -> Text
408−singleton = unstream . S.singleton . safe
409−{-# INLINE [1] singleton #-}
411-- -----------------------------------------------------------------------------
433-- -----------------------------------------------------------------------------
412-- * Basic functions
434-- * Basic functions
@@ -438,6 +460,7 @@ append a@(Text arr1 off1 len1) b@(Text arr2 off2 len2)
438 | otherwise = overflowError "append"
460 | otherwise = overflowError "append"
440 len = len1+len2
462 len = len1+len2
463+ x :: ST s (A.MArray s)
442 arr <- A.new len
465 arr <- A.new len
443 A.copyI arr 0 arr1 off1 len1
466 A.copyI arr 0 arr1 off1 len1
@@ -463,8 +486,8 @@ head t = S.head (stream t)
463uncons :: Text -> Maybe (Char, Text)
486uncons :: Text -> Maybe (Char, Text)
464uncons t@(Text arr off len)
487uncons t@(Text arr off len)
465 | len <= 0 = Nothing
488 | len <= 0 = Nothing
489+ | otherwise = Just $ let !(Iter c d) = iter t 0
466− | otherwise = Just (c, text arr (off+d) (len-d))
490+ in (c, text arr (off+d) (len-d))
467− where Iter c d = iter t 0
468{-# INLINE [1] uncons #-}
491{-# INLINE [1] uncons #-}
470-- | Lifted from Control.Arrow and specialized.
493-- | Lifted from Control.Arrow and specialized.
@@ -549,7 +572,9 @@ isSingleton = S.isSingleton . stream
549-- Subject to fusion.
572-- Subject to fusion.
550length :: Text -> Int
573length :: Text -> Int
551length t = S.length (stream t)
574length t = S.length (stream t)
552−{-# INLINE length #-}
575+{-# INLINE [0] length #-}
576+-- length needs to be phased after the compareN/length rules otherwise
577+-- it may inline before the rules have an opportunity to fire.
554-- | /O(n)/ Compare the count of characters in a 'Text' to a number.
579-- | /O(n)/ Compare the count of characters in a 'Text' to a number.
555-- Subject to fusion.
580-- Subject to fusion.
@@ -568,32 +593,32 @@ compareLength t n = S.compareLengthI (stream t) n
570"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
595"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
571− (==) (length t) n = compareLength t n == EQ
596+ eqInt (length t) n = compareLength t n == EQ
575"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
600"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
576− (/=) (length t) n = compareLength t n /= EQ
601+ neInt (length t) n = compareLength t n /= EQ
580"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
605"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
581− (<) (length t) n = compareLength t n == LT
606+ ltInt (length t) n = compareLength t n == LT
585"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
610"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
586− (<=) (length t) n = compareLength t n /= GT
611+ leInt (length t) n = compareLength t n /= GT
590"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
615"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
591− (>) (length t) n = compareLength t n == GT
616+ gtInt (length t) n = compareLength t n == GT
595"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
620"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
596− (>=) (length t) n = compareLength t n /= LT
621+ geInt (length t) n = compareLength t n /= LT
599-- -----------------------------------------------------------------------------
624-- -----------------------------------------------------------------------------
@@ -624,22 +649,48 @@ reverse :: Text -> Text
624reverse t = S.reverse (stream t)
649reverse t = S.reverse (stream t)
625{-# INLINE reverse #-}
650{-# INLINE reverse #-}
627−-- | /O(m+n)/ Replace every occurrence of one substring with another.
652+-- | /O(m+n)/ Replace every non-overlapping occurrence of @needle@ in
653+-- @haystack@ with @replacement@.
655+-- This function behaves as though it was defined as follows:
658+-- replace needle replacement haystack =
659+-- 'intercalate' replacement ('splitOn' needle haystack)
662+-- As this suggests, each occurrence is replaced exactly once. So if
663+-- @needle@ occurs in @replacement@, that occurrence will /not/ itself
664+-- be replaced recursively:
666+-- > replace "oo" "foo" "oo" == "foo"
668+-- In cases where several instances of @needle@ overlap, only the
669+-- first one will be replaced:
671+-- > replace "ofo" "bar" "ofofo" == "barfo"
629-- In (unlikely) bad cases, this function's time complexity degrades
673-- In (unlikely) bad cases, this function's time complexity degrades
630-- towards /O(n*m)/.
674-- towards /O(n*m)/.
631−replace :: Text -> Text -> Text -> Text
675+replace :: Text
676+ -- ^ @needle@ to search for. If this string is empty, an
677+ -- error will occur.
679+ -- ^ @replacement@ to replace @needle@ with.
681+ -- ^ @haystack@ in which to search.
632replace needle@(Text _ _ neeLen)
683replace needle@(Text _ _ neeLen)
633 (Text repArr repOff repLen)
684 (Text repArr repOff repLen)
634 haystack@(Text hayArr hayOff hayLen)
685 haystack@(Text hayArr hayOff hayLen)
635 | neeLen == 0 = emptyError "replace"
686 | neeLen == 0 = emptyError "replace"
636 | L.null ixs = haystack
687 | L.null ixs = haystack
637 | len > 0 = Text (A.run x) 0 len
688 | len > 0 = Text (A.run x) 0 len
638− | len < 0 = overflowError "replace"
639 | otherwise = empty
689 | otherwise = empty
641 ixs = indices needle haystack
691 ixs = indices needle haystack
642− len = hayLen - (neeLen - repLen) * L.length ixs
692+ len = hayLen - (neeLen - repLen) `mul` L.length ixs
693+ x :: ST s (A.MArray s)
644 marr <- A.new len
695 marr <- A.new len
645 let loop (i:is) o d = do
696 let loop (i:is) o d = do
@@ -669,9 +720,8 @@ replace needle@(Text _ _ neeLen)
669-- /Note/: In some languages, case conversion is a locale- and
720-- /Note/: In some languages, case conversion is a locale- and
670-- context-dependent operation. The case conversion functions in this
721-- context-dependent operation. The case conversion functions in this
671-- module are /not/ locale sensitive. Programs that require locale
722-- module are /not/ locale sensitive. Programs that require locale
672−-- sensitivity should use appropriate versions of the case mapping
723+-- sensitivity should use appropriate versions of the
673−-- functions from the @text-icu@ package:
674−-- <http://hackage.haskell.org/package/text-icu>
724+-- <http://hackage.haskell.org/package/text-icu-0.6.3.7/docs/Data-Text-ICU.html#g:4 case mapping functions from the text-icu package >.
676-- | /O(n)/ Convert a string to folded case. Subject to fusion.
726-- | /O(n)/ Convert a string to folded case. Subject to fusion.
@@ -691,7 +741,7 @@ replace needle@(Text _ _ neeLen)
691-- instead of itself.
741-- instead of itself.
692toCaseFold :: Text -> Text
742toCaseFold :: Text -> Text
693toCaseFold t = unstream (S.toCaseFold (stream t))
743toCaseFold t = unstream (S.toCaseFold (stream t))
694−{-# INLINE [0] toCaseFold #-}
744+{-# INLINE toCaseFold #-}
696-- | /O(n)/ Convert a string to lower case, using simple case
746-- | /O(n)/ Convert a string to lower case, using simple case
697-- conversion. Subject to fusion.
747-- conversion. Subject to fusion.
@@ -851,6 +901,7 @@ concat ts = case ts' of
852 ts' = L.filter (not . null) ts
902 ts' = L.filter (not . null) ts
853 len = sumP "concat" $ L.map lengthWord16 ts'
903 len = sumP "concat" $ L.map lengthWord16 ts'
904+ go :: ST s (A.MArray s)
855 arr <- A.new len
906 arr <- A.new len
856 let step i (Text a o l) =
907 let step i (Text a o l) =
@@ -864,13 +915,13 @@ concatMap f = concat . foldr ((:) . f) []
864{-# INLINE concatMap #-}
915{-# INLINE concatMap #-}
866-- | /O(n)/ 'any' @p@ @t@ determines whether any character in the
917-- | /O(n)/ 'any' @p@ @t@ determines whether any character in the
867−-- 'Text' @t@ satisifes the predicate @p@. Subject to fusion.
918+-- 'Text' @t@ satisfies the predicate @p@. Subject to fusion.
868any :: (Char -> Bool) -> Text -> Bool
919any :: (Char -> Bool) -> Text -> Bool
869any p t = S.any p (stream t)
920any p t = S.any p (stream t)
870{-# INLINE any #-}
921{-# INLINE any #-}
872-- | /O(n)/ 'all' @p@ @t@ determines whether all characters in the
923-- | /O(n)/ 'all' @p@ @t@ determines whether all characters in the
873−-- 'Text' @t@ satisify the predicate @p@. Subject to fusion.
924+-- 'Text' @t@ satisfy the predicate @p@. Subject to fusion.
874all :: (Char -> Bool) -> Text -> Bool
925all :: (Char -> Bool) -> Text -> Bool
875all p t = S.all p (stream t)
926all p t = S.all p (stream t)
876{-# INLINE all #-}
927{-# INLINE all #-}
@@ -961,10 +1012,10 @@ replicate n t@(Text a o l)
961 | n <= 0 || l <= 0 = empty
1012 | n <= 0 || l <= 0 = empty
962 | n == 1 = t
1013 | n == 1 = t
963 | isSingleton t = replicateChar n (unsafeHead t)
1014 | isSingleton t = replicateChar n (unsafeHead t)
964− | n <= maxBound `quot` l = Text (A.run x) 0 len
1015+ | otherwise = Text (A.run x) 0 len
965− | otherwise = overflowError "replicate"
967− len = l * n
1017+ len = l `mul` n
1018+ x :: ST s (A.MArray s)
969 arr <- A.new len
1020 arr <- A.new len
970 let loop !d !i | i >= n = return arr
1021 let loop !d !i | i >= n = return arr
@@ -1101,6 +1152,27 @@ takeWhile p t@(Text arr off len) = loop 0
1101 unstream (S.takeWhile p (stream t)) = takeWhile p t
1152 unstream (S.takeWhile p (stream t)) = takeWhile p t
1155+-- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text',
1156+-- returns the longest suffix (possibly empty) of elements that
1157+-- satisfy @p@. Subject to fusion.
1160+-- > takeWhileEnd (=='o') "foo" == "oo"
1161+takeWhileEnd :: (Char -> Bool) -> Text -> Text
1162+takeWhileEnd p t@(Text arr off len) = loop (len-1) len
1163+ where loop !i !l | l <= 0 = t
1164+ | p c = loop (i+d) (l+d)
1165+ | otherwise = text arr (off+l) (len-l)
1166+ where (c,d) = reverseIter t i
1167+{-# INLINE [1] takeWhileEnd #-}
1170+"TEXT takeWhileEnd -> fused" [~1] forall p t.
1171+ takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))
1172+"TEXT takeWhileEnd -> unfused" [1] forall p t.
1173+ S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t
1104-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1176-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1105-- 'takeWhile' @p@ @t@. Subject to fusion.
1177-- 'takeWhile' @p@ @t@. Subject to fusion.
1106dropWhile :: (Char -> Bool) -> Text -> Text
1178dropWhile :: (Char -> Bool) -> Text -> Text
@@ -1119,8 +1191,9 @@ dropWhile p t@(Text arr off len) = loop 0 0
1121-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
1193-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
1122−-- dropping characters that fail the predicate @p@ from the end of
1194+-- dropping characters that satisfy the predicate @p@ from the end of
1123-- @t@. Subject to fusion.
1195-- @t@. Subject to fusion.
1124-- Examples:
1197-- Examples:
1126-- > dropWhileEnd (=='.') "foo..." == "foo"
1199-- > dropWhileEnd (=='.') "foo..." == "foo"
@@ -1140,7 +1213,7 @@ dropWhileEnd p t@(Text arr off len) = loop (len-1) len
1142-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
1215-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
1143−-- dropping characters that fail the predicate @p@ from both the
1216+-- dropping characters that satisfy the predicate @p@ from both the
1144-- beginning and end of @t@. Subject to fusion.
1217-- beginning and end of @t@. Subject to fusion.
1145dropAround :: (Char -> Bool) -> Text -> Text
1218dropAround :: (Char -> Bool) -> Text -> Text
1146dropAround p = dropWhile p . dropWhileEnd p
1219dropAround p = dropWhile p . dropWhileEnd p
@@ -1235,9 +1308,9 @@ tails t | null t = [empty]
1235-- copies to create substrings; they just construct new 'Text's that
1308-- copies to create substrings; they just construct new 'Text's that
1236-- are slices of the original.
1309-- are slices of the original.
1238−-- | /O(m+n)/ Break a 'Text' into pieces separated by the first
1311+-- | /O(m+n)/ Break a 'Text' into pieces separated by the first 'Text'
1239−-- 'Text' argument, consuming the delimiter. An empty delimiter is
1312+-- argument (which cannot be empty), consuming the delimiter. An empty
1240−-- invalid, and will cause an error to be raised.
1313+-- delimiter is invalid, and will cause an error to be raised.
1242-- Examples:
1315-- Examples:
@@ -1250,9 +1323,16 @@ tails t | null t = [empty]
1250-- > intercalate s . splitOn s == id
1323-- > intercalate s . splitOn s == id
1251-- > splitOn (singleton c) == split (==c)
1324-- > splitOn (singleton c) == split (==c)
1326+-- (Note: the string @s@ to split on above cannot be empty.)
1253-- In (unlikely) bad cases, this function's time complexity degrades
1328-- In (unlikely) bad cases, this function's time complexity degrades
1254-- towards /O(n*m)/.
1329-- towards /O(n*m)/.
1255−splitOn :: Text -> Text -> [Text]
1330+splitOn :: Text
1331+ -- ^ String to split on. If this string is empty, an error
1256splitOn pat@(Text _ _ l) src@(Text arr off len)
1336splitOn pat@(Text _ _ l) src@(Text arr off len)
1257 | l <= 0 = emptyError "splitOn"
1337 | l <= 0 = emptyError "splitOn"
1258 | isSingleton pat = split (== unsafeHead pat) src
1338 | isSingleton pat = split (== unsafeHead pat) src
@@ -1460,7 +1540,7 @@ countChar c t = S.countChar c (stream t)
1460-- equivalent to a pair of 'unpack' operations.
1540-- equivalent to a pair of 'unpack' operations.
1461zip :: Text -> Text -> [(Char,Char)]
1541zip :: Text -> Text -> [(Char,Char)]
1462zip a b = S.unstreamList $ S.zipWith (,) (stream a) (stream b)
1542zip a b = S.unstreamList $ S.zipWith (,) (stream a) (stream b)
1463−{-# INLINE [0] zip #-}
1543+{-# INLINE zip #-}
1465-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
1545-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
1466-- given as the first argument, instead of a tupling function.
1546-- given as the first argument, instead of a tupling function.
@@ -1468,7 +1548,7 @@ zip a b = S.unstreamList $ S.zipWith (,) (stream a) (stream b)
1468zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
1548zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
1469zipWith f t1 t2 = unstream (S.zipWith g (stream t1) (stream t2))
1549zipWith f t1 t2 = unstream (S.zipWith g (stream t1) (stream t2))
1470 where g a b = safe (f a b)
1550 where g a b = safe (f a b)
1471−{-# INLINE [0] zipWith #-}
1551+{-# INLINE zipWith #-}
1473-- | /O(n)/ Breaks a 'Text' up into a list of words, delimited by 'Char's
1553-- | /O(n)/ Breaks a 'Text' up into a list of words, delimited by 'Char's
1474-- representing white space.
1554-- representing white space.
@@ -1668,6 +1748,7 @@ overflowError fun = P.error $ "Data.Text." ++ fun ++ ": size overflow"
1668copy :: Text -> Text
1748copy :: Text -> Text
1669copy (Text arr off len) = Text (A.run go) 0 len
1749copy (Text arr off len) = Text (A.run go) 0 len
1751+ go :: ST s (A.MArray s)
1672 marr <- A.new len
1753 marr <- A.new len
1673 A.copyI marr 0 arr off len
1754 A.copyI marr 0 arr off len