on 57e628e help sign in
text/Data/Text.hs
1750 lines 59 kB history raw
1{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types, UnboxedTuples #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
3#if __GLASGOW_HASKELL__ >= 702
4{-# LANGUAGE Trustworthy #-}
5#endif
6#if __GLASGOW_HASKELL__ >= 708
7{-# LANGUAGE TypeFamilies #-}
8#endif
10-- |
11-- Module : Data.Text
12-- Copyright : (c) 2009, 2010, 2011, 2012 Bryan O'Sullivan,
13-- (c) 2009 Duncan Coutts,
14-- (c) 2008, 2009 Tom Harper
15--
16-- License : BSD-style
17-- Maintainer : bos@serpentine.com
18-- Stability : experimental
19-- Portability : GHC
20--
21-- A time and space-efficient implementation of Unicode text.
22-- Suitable for performance critical use, both in terms of large data
23-- quantities and high speed.
24--
25-- /Note/: Read below the synopsis for important notes on the use of
26-- this module.
27--
28-- This module is intended to be imported @qualified@, to avoid name
29-- clashes with "Prelude" functions, e.g.
30--
31-- > import qualified Data.Text as T
32--
33-- To use an extended and very rich family of functions for working
34-- with Unicode text (including normalization, regular expressions,
35-- non-standard encodings, text breaking, and locales), see
36-- <http://hackage.haskell.org/package/text-icu the text-icu package >.
38module Data.Text
39 (
40 -- * Strict vs lazy types
41 -- $strict
43 -- * Acceptable data
44 -- $replacement
46 -- * Fusion
47 -- $fusion
49 -- * Types
50 Text
52 -- * Creation and elimination
53 , pack
54 , unpack
55 , singleton
56 , empty
58 -- * Basic interface
59 , cons
60 , snoc
61 , append
62 , uncons
63 , head
64 , last
65 , tail
66 , init
67 , null
68 , length
69 , compareLength
71 -- * Transformations
72 , map
73 , intercalate
74 , intersperse
75 , transpose
76 , reverse
77 , replace
79 -- ** Case conversion
80 -- $case
81 , toCaseFold
82 , toLower
83 , toUpper
84 , toTitle
86 -- ** Justification
87 , justifyLeft
88 , justifyRight
89 , center
91 -- * Folds
92 , foldl
93 , foldl'
94 , foldl1
95 , foldl1'
96 , foldr
97 , foldr1
99 -- ** Special folds
100 , concat
101 , concatMap
102 , any
103 , all
104 , maximum
105 , minimum
107 -- * Construction
109 -- ** Scans
110 , scanl
111 , scanl1
112 , scanr
113 , scanr1
115 -- ** Accumulating maps
116 , mapAccumL
117 , mapAccumR
119 -- ** Generation and unfolding
120 , replicate
121 , unfoldr
122 , unfoldrN
124 -- * Substrings
126 -- ** Breaking strings
127 , take
128 , takeEnd
129 , drop
130 , dropEnd
131 , takeWhile
132 , dropWhile
133 , dropWhileEnd
134 , dropAround
135 , strip
136 , stripStart
137 , stripEnd
138 , splitAt
139 , breakOn
140 , breakOnEnd
141 , break
142 , span
143 , group
144 , groupBy
145 , inits
146 , tails
148 -- ** Breaking into many substrings
149 -- $split
150 , splitOn
151 , split
152 , chunksOf
154 -- ** Breaking into lines and words
155 , lines
156 --, lines'
157 , words
158 , unlines
159 , unwords
161 -- * Predicates
162 , isPrefixOf
163 , isSuffixOf
164 , isInfixOf
166 -- ** View patterns
167 , stripPrefix
168 , stripSuffix
169 , commonPrefixes
171 -- * Searching
172 , filter
173 , breakOnAll
174 , find
175 , partition
177 -- , findSubstring
179 -- * Indexing
180 -- $index
181 , index
182 , findIndex
183 , count
185 -- * Zipping
186 , zip
187 , zipWith
189 -- -* Ordered text
190 -- , sort
192 -- * Low level operations
193 , copy
194 ) where
196import Prelude (Char, Bool(..), Int, Maybe(..), String,
197 Eq(..), Ord(..), Ordering(..), (++),
198 Read(..), Show(..),
199 (&&), (||), (+), (-), (.), ($), ($!), (>>),
200 not, return, otherwise, quot)
201#if defined(HAVE_DEEPSEQ)
202import Control.DeepSeq (NFData(rnf))
203#endif
204#if defined(ASSERTS)
205import Control.Exception (assert)
206#endif
207import Data.Char (isSpace)
208import Data.Data (Data(gfoldl, toConstr, gunfold, dataTypeOf), constrIndex,
209 Constr, mkConstr, DataType, mkDataType, Fixity(Prefix))
210import Control.Monad (foldM)
211import Control.Monad.ST (ST)
212import qualified Data.Text.Array as A
213import qualified Data.List as L
214import Data.Monoid (Monoid(..))
215import Data.String (IsString(..))
216import qualified Data.Text.Internal.Fusion as S
217import qualified Data.Text.Internal.Fusion.Common as S
218import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
219import Data.Text.Internal.Private (span_)
220import Data.Text.Internal (Text(..), empty, empty_, firstf, mul, safe, text)
221import qualified Prelude as P
222import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
223 reverseIter_, unsafeHead, unsafeTail)
224import Data.Text.Internal.Unsafe.Char (unsafeChr, unsafeWrite)
225import qualified Data.Text.Internal.Functions as F
226import qualified Data.Text.Internal.Encoding.Utf16 as U16
227import Data.Text.Internal.Search (indices)
228#if defined(__HADDOCK__)
229import Data.ByteString (ByteString)
230import qualified Data.Text.Lazy as L
231import Data.Int (Int64)
232#endif
233#if __GLASGOW_HASKELL__ >= 702
234import qualified GHC.CString as GHC
235#else
236import qualified GHC.Base as GHC
237#endif
238#if __GLASGOW_HASKELL__ >= 708
239import qualified GHC.Exts as Exts
240#endif
241import GHC.Prim (Addr#)
243-- $strict
244--
245-- This package provides both strict and lazy 'Text' types. The
246-- strict type is provided by the "Data.Text" module, while the lazy
247-- type is provided by the "Data.Text.Lazy" module. Internally, the
248-- lazy @Text@ type consists of a list of strict chunks.
249--
250-- The strict 'Text' type requires that an entire string fit into
251-- memory at once. The lazy 'Data.Text.Lazy.Text' type is capable of
252-- streaming strings that are larger than memory using a small memory
253-- footprint. In many cases, the overhead of chunked streaming makes
254-- the lazy 'Data.Text.Lazy.Text' type slower than its strict
255-- counterpart, but this is not always the case. Sometimes, the time
256-- complexity of a function in one module may be different from the
257-- other, due to their differing internal structures.
258--
259-- Each module provides an almost identical API, with the main
260-- difference being that the strict module uses 'Int' values for
261-- lengths and counts, while the lazy module uses 'Data.Int.Int64'
262-- lengths.
264-- $replacement
265--
266-- A 'Text' value is a sequence of Unicode scalar values, as defined
267-- in
268-- <http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#page=35 §3.9, definition D76 of the Unicode 5.2 standard >.
269-- As such, a 'Text' cannot contain values in the range U+D800 to
270-- U+DFFF inclusive. Haskell implementations admit all Unicode code
271-- points
272-- (<http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#page=13 §3.4, definition D10 >)
273-- as 'Char' values, including code points from this invalid range.
274-- This means that there are some 'Char' values that are not valid
275-- Unicode scalar values, and the functions in this module must handle
276-- those cases.
277--
278-- Within this module, many functions construct a 'Text' from one or
279-- more 'Char' values. Those functions will substitute 'Char' values
280-- that are not valid Unicode scalar values with the replacement
281-- character \"&#xfffd;\" (U+FFFD). Functions that perform this
282-- inspection and replacement are documented with the phrase
283-- \"Performs replacement on invalid scalar values\".
284--
285-- (One reason for this policy of replacement is that internally, a
286-- 'Text' value is represented as packed UTF-16 data. Values in the
287-- range U+D800 through U+DFFF are used by UTF-16 to denote surrogate
288-- code points, and so cannot be represented. The functions replace
289-- invalid scalar values, instead of dropping them, as a security
290-- measure. For details, see
291-- <http://unicode.org/reports/tr36/#Deletion_of_Noncharacters Unicode Technical Report 36, §3.5 >.)
293-- $fusion
294--
295-- Most of the functions in this module are subject to /fusion/,
296-- meaning that a pipeline of such functions will usually allocate at
297-- most one 'Text' value.
298--
299-- As an example, consider the following pipeline:
300--
301-- > import Data.Text as T
302-- > import Data.Text.Encoding as E
303-- > import Data.ByteString (ByteString)
304-- >
305-- > countChars :: ByteString -> Int
306-- > countChars = T.length . T.toUpper . E.decodeUtf8
307--
308-- From the type signatures involved, this looks like it should
309-- allocate one 'Data.ByteString.ByteString' value, and two 'Text'
310-- values. However, when a module is compiled with optimisation
311-- enabled under GHC, the two intermediate 'Text' values will be
312-- optimised away, and the function will be compiled down to a single
313-- loop over the source 'Data.ByteString.ByteString'.
314--
315-- Functions that can be fused by the compiler are documented with the
316-- phrase \"Subject to fusion\".
318instance Eq Text where
319 Text arrA offA lenA == Text arrB offB lenB
320 | lenA == lenB = A.equal arrA offA arrB offB lenA
321 | otherwise = False
322 {-# INLINE (==) #-}
324instance Ord Text where
325 compare = compareText
327instance Show Text where
328 showsPrec p ps r = showsPrec p (unpack ps) r
330instance Read Text where
331 readsPrec p str = [(pack x,y) | (x,y) <- readsPrec p str]
333instance Monoid Text where
334 mempty = empty
335 mappend = append
336 mconcat = concat
338instance IsString Text where
339 fromString = pack
341#if __GLASGOW_HASKELL__ >= 708
342instance Exts.IsList Text where
343 type Item Text = Char
344 fromList = pack
345 toList = unpack
346#endif
348#if defined(HAVE_DEEPSEQ)
349instance NFData Text where rnf !_ = ()
350#endif
352-- | This instance preserves data abstraction at the cost of inefficiency.
353-- We omit reflection services for the sake of data abstraction.
354--
355-- This instance was created by copying the updated behavior of
356-- @"Data.Set".@'Data.Set.Set' and @"Data.Map".@'Data.Map.Map'. If you
357-- feel a mistake has been made, please feel free to submit
358-- improvements.
359--
360-- The original discussion is archived here:
361-- <http://groups.google.com/group/haskell-cafe/browse_thread/thread/b5bbb1b28a7e525d/0639d46852575b93 could we get a Data instance for Data.Text.Text? >
362--
363-- The followup discussion that changed the behavior of 'Data.Set.Set'
364-- and 'Data.Map.Map' is archived here:
365-- <http://markmail.org/message/trovdc6zkphyi3cr#query:+page:1+mid:a46der3iacwjcf6n+state:results Proposal: Allow gunfold for Data.Map, ... >
367instance Data Text where
368 gfoldl f z txt = z pack `f` (unpack txt)
369 toConstr _ = packConstr
370 gunfold k z c = case constrIndex c of
371 1 -> k (z pack)
372 _ -> P.error "gunfold"
373 dataTypeOf _ = textDataType
375packConstr :: Constr
376packConstr = mkConstr textDataType "pack" [] Prefix
378textDataType :: DataType
379textDataType = mkDataType "Data.Text.Text" [packConstr]
381-- | /O(n)/ Compare two 'Text' values lexicographically.
382compareText :: Text -> Text -> Ordering
383compareText ta@(Text _arrA _offA lenA) tb@(Text _arrB _offB lenB)
384 | lenA == 0 && lenB == 0 = EQ
385 | otherwise = go 0 0
386 where
387 go !i !j
388 | i >= lenA || j >= lenB = compare lenA lenB
389 | a < b = LT
390 | a > b = GT
391 | otherwise = go (i+di) (j+dj)
392 where Iter a di = iter ta i
393 Iter b dj = iter tb j
395-- -----------------------------------------------------------------------------
396-- * Conversion to/from 'Text'
398-- | /O(n)/ Convert a 'String' into a 'Text'. Subject to
399-- fusion. Performs replacement on invalid scalar values.
400pack :: String -> Text
401pack = unstream . S.map safe . S.streamList
402{-# INLINE [1] pack #-}
404-- | /O(n)/ Convert a 'Text' into a 'String'. Subject to fusion.
405unpack :: Text -> String
406unpack = S.unstreamList . stream
407{-# INLINE [1] unpack #-}
409-- | /O(n)/ Convert a literal string into a Text. Subject to fusion.
410unpackCString# :: Addr# -> Text
411unpackCString# addr# = unstream (S.streamCString# addr#)
412{-# NOINLINE unpackCString# #-}
414{-# RULES "TEXT literal" forall a.
415 unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
416 = unpackCString# a #-}
418{-# RULES "TEXT literal UTF8" forall a.
419 unstream (S.map safe (S.streamList (GHC.unpackCStringUtf8# a)))
420 = unpackCString# a #-}
422{-# RULES "TEXT empty literal"
423 unstream (S.map safe (S.streamList []))
424 = empty_ #-}
426{-# RULES "TEXT singleton literal" forall a.
427 unstream (S.map safe (S.streamList [a]))
428 = singleton_ a #-}
430-- | /O(1)/ Convert a character into a Text. Subject to fusion.
431-- Performs replacement on invalid scalar values.
432singleton :: Char -> Text
433singleton = unstream . S.singleton . safe
434{-# INLINE [1] singleton #-}
436{-# RULES "TEXT singleton" forall a.
437 unstream (S.singleton (safe a))
438 = singleton_ a #-}
440-- This is intended to reduce inlining bloat.
441singleton_ :: Char -> Text
442singleton_ c = Text (A.run x) 0 len
443 where x :: ST s (A.MArray s)
444 x = do arr <- A.new len
445 _ <- unsafeWrite arr 0 d
446 return arr
447 len | d < '\x10000' = 1
448 | otherwise = 2
449 d = safe c
450{-# NOINLINE singleton_ #-}
452-- -----------------------------------------------------------------------------
453-- * Basic functions
455-- | /O(n)/ Adds a character to the front of a 'Text'. This function
456-- is more costly than its 'List' counterpart because it requires
457-- copying a new array. Subject to fusion. Performs replacement on
458-- invalid scalar values.
459cons :: Char -> Text -> Text
460cons c t = unstream (S.cons (safe c) (stream t))
461{-# INLINE cons #-}
463infixr 5 `cons`
465-- | /O(n)/ Adds a character to the end of a 'Text'. This copies the
466-- entire array in the process, unless fused. Subject to fusion.
467-- Performs replacement on invalid scalar values.
468snoc :: Text -> Char -> Text
469snoc t c = unstream (S.snoc (stream t) (safe c))
470{-# INLINE snoc #-}
472-- | /O(n)/ Appends one 'Text' to the other by copying both of them
473-- into a new 'Text'. Subject to fusion.
474append :: Text -> Text -> Text
475append a@(Text arr1 off1 len1) b@(Text arr2 off2 len2)
476 | len1 == 0 = b
477 | len2 == 0 = a
478 | len > 0 = Text (A.run x) 0 len
479 | otherwise = overflowError "append"
480 where
481 len = len1+len2
482 x :: ST s (A.MArray s)
483 x = do
484 arr <- A.new len
485 A.copyI arr 0 arr1 off1 len1
486 A.copyI arr len1 arr2 off2 len
487 return arr
488{-# NOINLINE append #-}
490{-# RULES
491"TEXT append -> fused" [~1] forall t1 t2.
492 append t1 t2 = unstream (S.append (stream t1) (stream t2))
493"TEXT append -> unfused" [1] forall t1 t2.
494 unstream (S.append (stream t1) (stream t2)) = append t1 t2
495 #-}
497-- | /O(1)/ Returns the first character of a 'Text', which must be
498-- non-empty. Subject to fusion.
499head :: Text -> Char
500head t = S.head (stream t)
501{-# INLINE head #-}
503-- | /O(1)/ Returns the first character and rest of a 'Text', or
504-- 'Nothing' if empty. Subject to fusion.
505uncons :: Text -> Maybe (Char, Text)
506uncons t@(Text arr off len)
507 | len <= 0 = Nothing
508 | otherwise = Just (c, text arr (off+d) (len-d))
509 where Iter c d = iter t 0
510{-# INLINE [1] uncons #-}
512-- | Lifted from Control.Arrow and specialized.
513second :: (b -> c) -> (a,b) -> (a,c)
514second f (a, b) = (a, f b)
516-- | /O(1)/ Returns the last character of a 'Text', which must be
517-- non-empty. Subject to fusion.
518last :: Text -> Char
519last (Text arr off len)
520 | len <= 0 = emptyError "last"
521 | n < 0xDC00 || n > 0xDFFF = unsafeChr n
522 | otherwise = U16.chr2 n0 n
523 where n = A.unsafeIndex arr (off+len-1)
524 n0 = A.unsafeIndex arr (off+len-2)
525{-# INLINE [1] last #-}
527{-# RULES
528"TEXT last -> fused" [~1] forall t.
529 last t = S.last (stream t)
530"TEXT last -> unfused" [1] forall t.
531 S.last (stream t) = last t
532 #-}
534-- | /O(1)/ Returns all characters after the head of a 'Text', which
535-- must be non-empty. Subject to fusion.
536tail :: Text -> Text
537tail t@(Text arr off len)
538 | len <= 0 = emptyError "tail"
539 | otherwise = text arr (off+d) (len-d)
540 where d = iter_ t 0
541{-# INLINE [1] tail #-}
543{-# RULES
544"TEXT tail -> fused" [~1] forall t.
545 tail t = unstream (S.tail (stream t))
546"TEXT tail -> unfused" [1] forall t.
547 unstream (S.tail (stream t)) = tail t
548 #-}
550-- | /O(1)/ Returns all but the last character of a 'Text', which must
551-- be non-empty. Subject to fusion.
552init :: Text -> Text
553init (Text arr off len) | len <= 0 = emptyError "init"
554 | n >= 0xDC00 && n <= 0xDFFF = text arr off (len-2)
555 | otherwise = text arr off (len-1)
556 where
557 n = A.unsafeIndex arr (off+len-1)
558{-# INLINE [1] init #-}
560{-# RULES
561"TEXT init -> fused" [~1] forall t.
562 init t = unstream (S.init (stream t))
563"TEXT init -> unfused" [1] forall t.
564 unstream (S.init (stream t)) = init t
565 #-}
567-- | /O(1)/ Tests whether a 'Text' is empty or not. Subject to
568-- fusion.
569null :: Text -> Bool
570null (Text _arr _off len) =
571#if defined(ASSERTS)
572 assert (len >= 0) $
573#endif
574 len <= 0
575{-# INLINE [1] null #-}
577{-# RULES
578"TEXT null -> fused" [~1] forall t.
579 null t = S.null (stream t)
580"TEXT null -> unfused" [1] forall t.
581 S.null (stream t) = null t
582 #-}
584-- | /O(1)/ Tests whether a 'Text' contains exactly one character.
585-- Subject to fusion.
586isSingleton :: Text -> Bool
587isSingleton = S.isSingleton . stream
588{-# INLINE isSingleton #-}
590-- | /O(n)/ Returns the number of characters in a 'Text'.
591-- Subject to fusion.
592length :: Text -> Int
593length t = S.length (stream t)
594{-# INLINE length #-}
596-- | /O(n)/ Compare the count of characters in a 'Text' to a number.
597-- Subject to fusion.
598--
599-- This function gives the same answer as comparing against the result
600-- of 'length', but can short circuit if the count of characters is
601-- greater than the number, and hence be more efficient.
602compareLength :: Text -> Int -> Ordering
603compareLength t n = S.compareLengthI (stream t) n
604{-# INLINE [1] compareLength #-}
606{-# RULES
607"TEXT compareN/length -> compareLength" [~1] forall t n.
608 compare (length t) n = compareLength t n
609 #-}
611{-# RULES
612"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
613 (==) (length t) n = compareLength t n == EQ
614 #-}
616{-# RULES
617"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
618 (/=) (length t) n = compareLength t n /= EQ
619 #-}
621{-# RULES
622"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
623 (<) (length t) n = compareLength t n == LT
624 #-}
626{-# RULES
627"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
628 (<=) (length t) n = compareLength t n /= GT
629 #-}
631{-# RULES
632"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
633 (>) (length t) n = compareLength t n == GT
634 #-}
636{-# RULES
637"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
638 (>=) (length t) n = compareLength t n /= LT
639 #-}
641-- -----------------------------------------------------------------------------
642-- * Transformations
643-- | /O(n)/ 'map' @f@ @t@ is the 'Text' obtained by applying @f@ to
644-- each element of @t@. Subject to fusion. Performs replacement on
645-- invalid scalar values.
646map :: (Char -> Char) -> Text -> Text
647map f t = unstream (S.map (safe . f) (stream t))
648{-# INLINE [1] map #-}
650-- | /O(n)/ The 'intercalate' function takes a 'Text' and a list of
651-- 'Text's and concatenates the list after interspersing the first
652-- argument between each element of the list.
653intercalate :: Text -> [Text] -> Text
654intercalate t = concat . (F.intersperse t)
655{-# INLINE intercalate #-}
657-- | /O(n)/ The 'intersperse' function takes a character and places it
658-- between the characters of a 'Text'. Subject to fusion. Performs
659-- replacement on invalid scalar values.
660intersperse :: Char -> Text -> Text
661intersperse c t = unstream (S.intersperse (safe c) (stream t))
662{-# INLINE intersperse #-}
664-- | /O(n)/ Reverse the characters of a string. Subject to fusion.
665reverse :: Text -> Text
666reverse t = S.reverse (stream t)
667{-# INLINE reverse #-}
669-- | /O(m+n)/ Replace every non-overlapping occurrence of @needle@ in
670-- @haystack@ with @replacement@.
671--
672-- This function behaves as though it was defined as follows:
673--
674-- @
675-- replace needle replacement haystack =
676-- 'intercalate' replacement ('splitOn' needle haystack)
677-- @
678--
679-- As this suggests, each occurrence is replaced exactly once. So if
680-- @needle@ occurs in @replacement@, that occurrence will /not/ itself
681-- be replaced recursively:
682--
683-- > replace "oo" "foo" "oo" == "foo"
684--
685-- In cases where several instances of @needle@ overlap, only the
686-- first one will be replaced:
687--
688-- > replace "ofo" "bar" "ofofo" == "barfo"
689--
690-- In (unlikely) bad cases, this function's time complexity degrades
691-- towards /O(n*m)/.
692replace :: Text
693 -- ^ @needle@ to search for. If this string is empty, an
694 -- error will occur.
695 -> Text
696 -- ^ @replacement@ to replace @needle@ with.
697 -> Text
698 -- ^ @haystack@ in which to search.
699 -> Text
700replace needle@(Text _ _ neeLen)
701 (Text repArr repOff repLen)
702 haystack@(Text hayArr hayOff hayLen)
703 | neeLen == 0 = emptyError "replace"
704 | L.null ixs = haystack
705 | len > 0 = Text (A.run x) 0 len
706 | otherwise = empty
707 where
708 ixs = indices needle haystack
709 len = hayLen - (neeLen - repLen) `mul` L.length ixs
710 x :: ST s (A.MArray s)
711 x = do
712 marr <- A.new len
713 let loop (i:is) o d = do
714 let d0 = d + i - o
715 d1 = d0 + repLen
716 A.copyI marr d hayArr (hayOff+o) d0
717 A.copyI marr d0 repArr repOff d1
718 loop is (i + neeLen) d1
719 loop [] o d = A.copyI marr d hayArr (hayOff+o) len
720 loop ixs 0 0
721 return marr
723-- ----------------------------------------------------------------------------
724-- ** Case conversions (folds)
726-- $case
727--
728-- When case converting 'Text' values, do not use combinators like
729-- @map toUpper@ to case convert each character of a string
730-- individually, as this gives incorrect results according to the
731-- rules of some writing systems. The whole-string case conversion
732-- functions from this module, such as @toUpper@, obey the correct
733-- case conversion rules. As a result, these functions may map one
734-- input character to two or three output characters. For examples,
735-- see the documentation of each function.
736--
737-- /Note/: In some languages, case conversion is a locale- and
738-- context-dependent operation. The case conversion functions in this
739-- module are /not/ locale sensitive. Programs that require locale
740-- sensitivity should use appropriate versions of the
741-- <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 >.
743-- | /O(n)/ Convert a string to folded case. Subject to fusion.
744--
745-- This function is mainly useful for performing caseless (also known
746-- as case insensitive) string comparisons.
747--
748-- A string @x@ is a caseless match for a string @y@ if and only if:
749--
750-- @toCaseFold x == toCaseFold y@
751--
752-- The result string may be longer than the input string, and may
753-- differ from applying 'toLower' to the input string. For instance,
754-- the Armenian small ligature \"&#xfb13;\" (men now, U+FB13) is case
755-- folded to the sequence \"&#x574;\" (men, U+0574) followed by
756-- \"&#x576;\" (now, U+0576), while the Greek \"&#xb5;\" (micro sign,
757-- U+00B5) is case folded to \"&#x3bc;\" (small letter mu, U+03BC)
758-- instead of itself.
759toCaseFold :: Text -> Text
760toCaseFold t = unstream (S.toCaseFold (stream t))
761{-# INLINE [0] toCaseFold #-}
763-- | /O(n)/ Convert a string to lower case, using simple case
764-- conversion. Subject to fusion.
765--
766-- The result string may be longer than the input string. For
767-- instance, \"&#x130;\" (Latin capital letter I with dot above,
768-- U+0130) maps to the sequence \"i\" (Latin small letter i, U+0069)
769-- followed by \" &#x307;\" (combining dot above, U+0307).
770toLower :: Text -> Text
771toLower t = unstream (S.toLower (stream t))
772{-# INLINE toLower #-}
774-- | /O(n)/ Convert a string to upper case, using simple case
775-- conversion. Subject to fusion.
776--
777-- The result string may be longer than the input string. For
778-- instance, the German \"&#xdf;\" (eszett, U+00DF) maps to the
779-- two-letter sequence \"SS\".
780toUpper :: Text -> Text
781toUpper t = unstream (S.toUpper (stream t))
782{-# INLINE toUpper #-}
784-- | /O(n)/ Convert a string to title case, using simple case
785-- conversion. Subject to fusion.
786--
787-- The first letter of the input is converted to title case, as is
788-- every subsequent letter that immediately follows a non-letter.
789-- Every letter that immediately follows another letter is converted
790-- to lower case.
791--
792-- The result string may be longer than the input string. For example,
793-- the Latin small ligature &#xfb02; (U+FB02) is converted to the
794-- sequence Latin capital letter F (U+0046) followed by Latin small
795-- letter l (U+006C).
796--
797-- /Note/: this function does not take language or culture specific
798-- rules into account. For instance, in English, different style
799-- guides disagree on whether the book name \"The Hill of the Red
800-- Fox\" is correctly title cased&#x2014;but this function will
801-- capitalize /every/ word.
802toTitle :: Text -> Text
803toTitle t = unstream (S.toTitle (stream t))
804{-# INLINE toTitle #-}
806-- | /O(n)/ Left-justify a string to the given length, using the
807-- specified fill character on the right. Subject to fusion.
808-- Performs replacement on invalid scalar values.
809--
810-- Examples:
811--
812-- > justifyLeft 7 'x' "foo" == "fooxxxx"
813-- > justifyLeft 3 'x' "foobar" == "foobar"
814justifyLeft :: Int -> Char -> Text -> Text
815justifyLeft k c t
816 | len >= k = t
817 | otherwise = t `append` replicateChar (k-len) c
818 where len = length t
819{-# INLINE [1] justifyLeft #-}
821{-# RULES
822"TEXT justifyLeft -> fused" [~1] forall k c t.
823 justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
824"TEXT justifyLeft -> unfused" [1] forall k c t.
825 unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
826 #-}
828-- | /O(n)/ Right-justify a string to the given length, using the
829-- specified fill character on the left. Performs replacement on
830-- invalid scalar values.
831--
832-- Examples:
833--
834-- > justifyRight 7 'x' "bar" == "xxxxbar"
835-- > justifyRight 3 'x' "foobar" == "foobar"
836justifyRight :: Int -> Char -> Text -> Text
837justifyRight k c t
838 | len >= k = t
839 | otherwise = replicateChar (k-len) c `append` t
840 where len = length t
841{-# INLINE justifyRight #-}
843-- | /O(n)/ Center a string to the given length, using the specified
844-- fill character on either side. Performs replacement on invalid
845-- scalar values.
846--
847-- Examples:
848--
849-- > center 8 'x' "HS" = "xxxHSxxx"
850center :: Int -> Char -> Text -> Text
851center k c t
852 | len >= k = t
853 | otherwise = replicateChar l c `append` t `append` replicateChar r c
854 where len = length t
855 d = k - len
856 r = d `quot` 2
857 l = d - r
858{-# INLINE center #-}
860-- | /O(n)/ The 'transpose' function transposes the rows and columns
861-- of its 'Text' argument. Note that this function uses 'pack',
862-- 'unpack', and the list version of transpose, and is thus not very
863-- efficient.
864transpose :: [Text] -> [Text]
865transpose ts = P.map pack (L.transpose (P.map unpack ts))
867-- -----------------------------------------------------------------------------
868-- * Reducing 'Text's (folds)
870-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
871-- (typically the left-identity of the operator), and a 'Text',
872-- reduces the 'Text' using the binary operator, from left to right.
873-- Subject to fusion.
874foldl :: (a -> Char -> a) -> a -> Text -> a
875foldl f z t = S.foldl f z (stream t)
876{-# INLINE foldl #-}
878-- | /O(n)/ A strict version of 'foldl'. Subject to fusion.
879foldl' :: (a -> Char -> a) -> a -> Text -> a
880foldl' f z t = S.foldl' f z (stream t)
881{-# INLINE foldl' #-}
883-- | /O(n)/ A variant of 'foldl' that has no starting value argument,
884-- and thus must be applied to a non-empty 'Text'. Subject to fusion.
885foldl1 :: (Char -> Char -> Char) -> Text -> Char
886foldl1 f t = S.foldl1 f (stream t)
887{-# INLINE foldl1 #-}
889-- | /O(n)/ A strict version of 'foldl1'. Subject to fusion.
890foldl1' :: (Char -> Char -> Char) -> Text -> Char
891foldl1' f t = S.foldl1' f (stream t)
892{-# INLINE foldl1' #-}
894-- | /O(n)/ 'foldr', applied to a binary operator, a starting value
895-- (typically the right-identity of the operator), and a 'Text',
896-- reduces the 'Text' using the binary operator, from right to left.
897-- Subject to fusion.
898foldr :: (Char -> a -> a) -> a -> Text -> a
899foldr f z t = S.foldr f z (stream t)
900{-# INLINE foldr #-}
902-- | /O(n)/ A variant of 'foldr' that has no starting value argument,
903-- and thus must be applied to a non-empty 'Text'. Subject to
904-- fusion.
905foldr1 :: (Char -> Char -> Char) -> Text -> Char
906foldr1 f t = S.foldr1 f (stream t)
907{-# INLINE foldr1 #-}
909-- -----------------------------------------------------------------------------
910-- ** Special folds
912-- | /O(n)/ Concatenate a list of 'Text's.
913concat :: [Text] -> Text
914concat ts = case ts' of
915 [] -> empty
916 [t] -> t
917 _ -> Text (A.run go) 0 len
918 where
919 ts' = L.filter (not . null) ts
920 len = sumP "concat" $ L.map lengthWord16 ts'
921 go :: ST s (A.MArray s)
922 go = do
923 arr <- A.new len
924 let step i (Text a o l) =
925 let !j = i + l in A.copyI arr i a o j >> return j
926 foldM step 0 ts' >> return arr
928-- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and
929-- concatenate the results.
930concatMap :: (Char -> Text) -> Text -> Text
931concatMap f = concat . foldr ((:) . f) []
932{-# INLINE concatMap #-}
934-- | /O(n)/ 'any' @p@ @t@ determines whether any character in the
935-- 'Text' @t@ satisifes the predicate @p@. Subject to fusion.
936any :: (Char -> Bool) -> Text -> Bool
937any p t = S.any p (stream t)
938{-# INLINE any #-}
940-- | /O(n)/ 'all' @p@ @t@ determines whether all characters in the
941-- 'Text' @t@ satisify the predicate @p@. Subject to fusion.
942all :: (Char -> Bool) -> Text -> Bool
943all p t = S.all p (stream t)
944{-# INLINE all #-}
946-- | /O(n)/ 'maximum' returns the maximum value from a 'Text', which
947-- must be non-empty. Subject to fusion.
948maximum :: Text -> Char
949maximum t = S.maximum (stream t)
950{-# INLINE maximum #-}
952-- | /O(n)/ 'minimum' returns the minimum value from a 'Text', which
953-- must be non-empty. Subject to fusion.
954minimum :: Text -> Char
955minimum t = S.minimum (stream t)
956{-# INLINE minimum #-}
958-- -----------------------------------------------------------------------------
959-- * Building 'Text's
961-- | /O(n)/ 'scanl' is similar to 'foldl', but returns a list of
962-- successive reduced values from the left. Subject to fusion.
963-- Performs replacement on invalid scalar values.
964--
965-- > scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]
966--
967-- Note that
968--
969-- > last (scanl f z xs) == foldl f z xs.
970scanl :: (Char -> Char -> Char) -> Char -> Text -> Text
971scanl f z t = unstream (S.scanl g z (stream t))
972 where g a b = safe (f a b)
973{-# INLINE scanl #-}
975-- | /O(n)/ 'scanl1' is a variant of 'scanl' that has no starting
976-- value argument. Subject to fusion. Performs replacement on
977-- invalid scalar values.
978--
979-- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...]
980scanl1 :: (Char -> Char -> Char) -> Text -> Text
981scanl1 f t | null t = empty
982 | otherwise = scanl f (unsafeHead t) (unsafeTail t)
983{-# INLINE scanl1 #-}
985-- | /O(n)/ 'scanr' is the right-to-left dual of 'scanl'. Performs
986-- replacement on invalid scalar values.
987--
988-- > scanr f v == reverse . scanl (flip f) v . reverse
989scanr :: (Char -> Char -> Char) -> Char -> Text -> Text
990scanr f z = S.reverse . S.reverseScanr g z . reverseStream
991 where g a b = safe (f a b)
992{-# INLINE scanr #-}
994-- | /O(n)/ 'scanr1' is a variant of 'scanr' that has no starting
995-- value argument. Subject to fusion. Performs replacement on
996-- invalid scalar values.
997scanr1 :: (Char -> Char -> Char) -> Text -> Text
998scanr1 f t | null t = empty
999 | otherwise = scanr f (last t) (init t)
1000{-# INLINE scanr1 #-}
1002-- | /O(n)/ Like a combination of 'map' and 'foldl''. Applies a
1003-- function to each element of a 'Text', passing an accumulating
1004-- parameter from left to right, and returns a final 'Text'. Performs
1005-- replacement on invalid scalar values.
1006mapAccumL :: (a -> Char -> (a,Char)) -> a -> Text -> (a, Text)
1007mapAccumL f z0 = S.mapAccumL g z0 . stream
1008 where g a b = second safe (f a b)
1009{-# INLINE mapAccumL #-}
1011-- | The 'mapAccumR' function behaves like a combination of 'map' and
1012-- a strict 'foldr'; it applies a function to each element of a
1013-- 'Text', passing an accumulating parameter from right to left, and
1014-- returning a final value of this accumulator together with the new
1015-- 'Text'.
1016-- Performs replacement on invalid scalar values.
1017mapAccumR :: (a -> Char -> (a,Char)) -> a -> Text -> (a, Text)
1018mapAccumR f z0 = second reverse . S.mapAccumL g z0 . reverseStream
1019 where g a b = second safe (f a b)
1020{-# INLINE mapAccumR #-}
1022-- -----------------------------------------------------------------------------
1023-- ** Generating and unfolding 'Text's
1025-- | /O(n*m)/ 'replicate' @n@ @t@ is a 'Text' consisting of the input
1026-- @t@ repeated @n@ times.
1027replicate :: Int -> Text -> Text
1028replicate n t@(Text a o l)
1029 | n <= 0 || l <= 0 = empty
1030 | n == 1 = t
1031 | isSingleton t = replicateChar n (unsafeHead t)
1032 | otherwise = Text (A.run x) 0 len
1033 where
1034 len = l `mul` n
1035 x :: ST s (A.MArray s)
1036 x = do
1037 arr <- A.new len
1038 let loop !d !i | i >= n = return arr
1039 | otherwise = let m = d + l
1040 in A.copyI arr d a o m >> loop m (i+1)
1041 loop 0 0
1042{-# INLINE [1] replicate #-}
1044{-# RULES
1045"TEXT replicate/singleton -> replicateChar" [~1] forall n c.
1046 replicate n (singleton c) = replicateChar n c
1047 #-}
1049-- | /O(n)/ 'replicateChar' @n@ @c@ is a 'Text' of length @n@ with @c@ the
1050-- value of every element. Subject to fusion.
1051replicateChar :: Int -> Char -> Text
1052replicateChar n c = unstream (S.replicateCharI n (safe c))
1053{-# INLINE replicateChar #-}
1055-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
1056-- function is analogous to the List 'L.unfoldr'. 'unfoldr' builds a
1057-- 'Text' from a seed value. The function takes the element and
1058-- returns 'Nothing' if it is done producing the 'Text', otherwise
1059-- 'Just' @(a,b)@. In this case, @a@ is the next 'Char' in the
1060-- string, and @b@ is the seed value for further production. Subject
1061-- to fusion. Performs replacement on invalid scalar values.
1062unfoldr :: (a -> Maybe (Char,a)) -> a -> Text
1063unfoldr f s = unstream (S.unfoldr (firstf safe . f) s)
1064{-# INLINE unfoldr #-}
1066-- | /O(n)/ Like 'unfoldr', 'unfoldrN' builds a 'Text' from a seed
1067-- value. However, the length of the result should be limited by the
1068-- first argument to 'unfoldrN'. This function is more efficient than
1069-- 'unfoldr' when the maximum length of the result is known and
1070-- correct, otherwise its performance is similar to 'unfoldr'. Subject
1071-- to fusion. Performs replacement on invalid scalar values.
1072unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Text
1073unfoldrN n f s = unstream (S.unfoldrN n (firstf safe . f) s)
1074{-# INLINE unfoldrN #-}
1076-- -----------------------------------------------------------------------------
1077-- * Substrings
1079-- | /O(n)/ 'take' @n@, applied to a 'Text', returns the prefix of the
1080-- 'Text' of length @n@, or the 'Text' itself if @n@ is greater than
1081-- the length of the Text. Subject to fusion.
1082take :: Int -> Text -> Text
1083take n t@(Text arr off len)
1084 | n <= 0 = empty
1085 | n >= len = t
1086 | otherwise = text arr off (iterN n t)
1087{-# INLINE [1] take #-}
1089iterN :: Int -> Text -> Int
1090iterN n t@(Text _arr _off len) = loop 0 0
1091 where loop !i !cnt
1092 | i >= len || cnt >= n = i
1093 | otherwise = loop (i+d) (cnt+1)
1094 where d = iter_ t i
1096{-# RULES
1097"TEXT take -> fused" [~1] forall n t.
1098 take n t = unstream (S.take n (stream t))
1099"TEXT take -> unfused" [1] forall n t.
1100 unstream (S.take n (stream t)) = take n t
1101 #-}
1103-- | /O(n)/ 'takeEnd' @n@ @t@ returns the suffix remaining after
1104-- taking @n@ characters from the end of @t@.
1106-- Examples:
1108-- > takeEnd 3 "foobar" == "bar"
1109takeEnd :: Int -> Text -> Text
1110takeEnd n t@(Text arr off len)
1111 | n <= 0 = empty
1112 | n >= len = t
1113 | otherwise = text arr (off+i) (len-i)
1114 where i = iterNEnd n t
1116iterNEnd :: Int -> Text -> Int
1117iterNEnd n t@(Text _arr _off len) = loop (len-1) n
1118 where loop i !m
1119 | i <= 0 = 0
1120 | m <= 1 = i
1121 | otherwise = loop (i+d) (m-1)
1122 where d = reverseIter_ t i
1124-- | /O(n)/ 'drop' @n@, applied to a 'Text', returns the suffix of the
1125-- 'Text' after the first @n@ characters, or the empty 'Text' if @n@
1126-- is greater than the length of the 'Text'. Subject to fusion.
1127drop :: Int -> Text -> Text
1128drop n t@(Text arr off len)
1129 | n <= 0 = t
1130 | n >= len = empty
1131 | otherwise = text arr (off+i) (len-i)
1132 where i = iterN n t
1133{-# INLINE [1] drop #-}
1135{-# RULES
1136"TEXT drop -> fused" [~1] forall n t.
1137 drop n t = unstream (S.drop n (stream t))
1138"TEXT drop -> unfused" [1] forall n t.
1139 unstream (S.drop n (stream t)) = drop n t
1140 #-}
1142-- | /O(n)/ 'dropEnd' @n@ @t@ returns the prefix remaining after
1143-- dropping @n@ characters from the end of @t@.
1145-- Examples:
1147-- > dropEnd 3 "foobar" == "foo"
1148dropEnd :: Int -> Text -> Text
1149dropEnd n t@(Text arr off len)
1150 | n <= 0 = t
1151 | n >= len = empty
1152 | otherwise = text arr off (iterNEnd n t)
1154-- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'Text',
1155-- returns the longest prefix (possibly empty) of elements that
1156-- satisfy @p@. Subject to fusion.
1157takeWhile :: (Char -> Bool) -> Text -> Text
1158takeWhile p t@(Text arr off len) = loop 0
1159 where loop !i | i >= len = t
1160 | p c = loop (i+d)
1161 | otherwise = text arr off i
1162 where Iter c d = iter t i
1163{-# INLINE [1] takeWhile #-}
1165{-# RULES
1166"TEXT takeWhile -> fused" [~1] forall p t.
1167 takeWhile p t = unstream (S.takeWhile p (stream t))
1168"TEXT takeWhile -> unfused" [1] forall p t.
1169 unstream (S.takeWhile p (stream t)) = takeWhile p t
1170 #-}
1172-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1173-- 'takeWhile' @p@ @t@. Subject to fusion.
1174dropWhile :: (Char -> Bool) -> Text -> Text
1175dropWhile p t@(Text arr off len) = loop 0 0
1176 where loop !i !l | l >= len = empty
1177 | p c = loop (i+d) (l+d)
1178 | otherwise = Text arr (off+i) (len-l)
1179 where Iter c d = iter t i
1180{-# INLINE [1] dropWhile #-}
1182{-# RULES
1183"TEXT dropWhile -> fused" [~1] forall p t.
1184 dropWhile p t = unstream (S.dropWhile p (stream t))
1185"TEXT dropWhile -> unfused" [1] forall p t.
1186 unstream (S.dropWhile p (stream t)) = dropWhile p t
1187 #-}
1189-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
1190-- dropping characters that fail the predicate @p@ from the end of
1191-- @t@. Subject to fusion.
1192-- Examples:
1194-- > dropWhileEnd (=='.') "foo..." == "foo"
1195dropWhileEnd :: (Char -> Bool) -> Text -> Text
1196dropWhileEnd p t@(Text arr off len) = loop (len-1) len
1197 where loop !i !l | l <= 0 = empty
1198 | p c = loop (i+d) (l+d)
1199 | otherwise = Text arr off l
1200 where (c,d) = reverseIter t i
1201{-# INLINE [1] dropWhileEnd #-}
1203{-# RULES
1204"TEXT dropWhileEnd -> fused" [~1] forall p t.
1205 dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))
1206"TEXT dropWhileEnd -> unfused" [1] forall p t.
1207 S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t
1208 #-}
1210-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
1211-- dropping characters that fail the predicate @p@ from both the
1212-- beginning and end of @t@. Subject to fusion.
1213dropAround :: (Char -> Bool) -> Text -> Text
1214dropAround p = dropWhile p . dropWhileEnd p
1215{-# INLINE [1] dropAround #-}
1217-- | /O(n)/ Remove leading white space from a string. Equivalent to:
1219-- > dropWhile isSpace
1220stripStart :: Text -> Text
1221stripStart = dropWhile isSpace
1222{-# INLINE [1] stripStart #-}
1224-- | /O(n)/ Remove trailing white space from a string. Equivalent to:
1226-- > dropWhileEnd isSpace
1227stripEnd :: Text -> Text
1228stripEnd = dropWhileEnd isSpace
1229{-# INLINE [1] stripEnd #-}
1231-- | /O(n)/ Remove leading and trailing white space from a string.
1232-- Equivalent to:
1234-- > dropAround isSpace
1235strip :: Text -> Text
1236strip = dropAround isSpace
1237{-# INLINE [1] strip #-}
1239-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
1240-- prefix of @t@ of length @n@, and whose second is the remainder of
1241-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
1242splitAt :: Int -> Text -> (Text, Text)
1243splitAt n t@(Text arr off len)
1244 | n <= 0 = (empty, t)
1245 | n >= len = (t, empty)
1246 | otherwise = let k = iterN n t
1247 in (text arr off k, text arr (off+k) (len-k))
1249-- | /O(n)/ 'span', applied to a predicate @p@ and text @t@, returns
1250-- a pair whose first element is the longest prefix (possibly empty)
1251-- of @t@ of elements that satisfy @p@, and whose second is the
1252-- remainder of the list.
1253span :: (Char -> Bool) -> Text -> (Text, Text)
1254span p t = case span_ p t of
1255 (# hd,tl #) -> (hd,tl)
1256{-# INLINE span #-}
1258-- | /O(n)/ 'break' is like 'span', but the prefix returned is
1259-- over elements that fail the predicate @p@.
1260break :: (Char -> Bool) -> Text -> (Text, Text)
1261break p = span (not . p)
1262{-# INLINE break #-}
1264-- | /O(n)/ Group characters in a string according to a predicate.
1265groupBy :: (Char -> Char -> Bool) -> Text -> [Text]
1266groupBy p = loop
1267 where
1268 loop t@(Text arr off len)
1269 | null t = []
1270 | otherwise = text arr off n : loop (text arr (off+n) (len-n))
1271 where Iter c d = iter t 0
1272 n = d + findAIndexOrEnd (not . p c) (Text arr (off+d) (len-d))
1274-- | Returns the /array/ index (in units of 'Word16') at which a
1275-- character may be found. This is /not/ the same as the logical
1276-- index returned by e.g. 'findIndex'.
1277findAIndexOrEnd :: (Char -> Bool) -> Text -> Int
1278findAIndexOrEnd q t@(Text _arr _off len) = go 0
1279 where go !i | i >= len || q c = i
1280 | otherwise = go (i+d)
1281 where Iter c d = iter t i
1283-- | /O(n)/ Group characters in a string by equality.
1284group :: Text -> [Text]
1285group = groupBy (==)
1287-- | /O(n)/ Return all initial segments of the given 'Text', shortest
1288-- first.
1289inits :: Text -> [Text]
1290inits t@(Text arr off len) = loop 0
1291 where loop i | i >= len = [t]
1292 | otherwise = Text arr off i : loop (i + iter_ t i)
1294-- | /O(n)/ Return all final segments of the given 'Text', longest
1295-- first.
1296tails :: Text -> [Text]
1297tails t | null t = [empty]
1298 | otherwise = t : tails (unsafeTail t)
1300-- $split
1302-- Splitting functions in this library do not perform character-wise
1303-- copies to create substrings; they just construct new 'Text's that
1304-- are slices of the original.
1306-- | /O(m+n)/ Break a 'Text' into pieces separated by the first 'Text'
1307-- argument (which cannot be empty), consuming the delimiter. An empty
1308-- delimiter is invalid, and will cause an error to be raised.
1310-- Examples:
1312-- > splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"]
1313-- > splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""]
1314-- > splitOn "x" "x" == ["",""]
1316-- and
1318-- > intercalate s . splitOn s == id
1319-- > splitOn (singleton c) == split (==c)
1321-- (Note: the string @s@ to split on above cannot be empty.)
1323-- In (unlikely) bad cases, this function's time complexity degrades
1324-- towards /O(n*m)/.
1325splitOn :: Text
1326 -- ^ String to split on. If this string is empty, an error
1327 -- will occur.
1328 -> Text
1329 -- ^ Input text.
1330 -> [Text]
1331splitOn pat@(Text _ _ l) src@(Text arr off len)
1332 | l <= 0 = emptyError "splitOn"
1333 | isSingleton pat = split (== unsafeHead pat) src
1334 | otherwise = go 0 (indices pat src)
1335 where
1336 go !s (x:xs) = text arr (s+off) (x-s) : go (x+l) xs
1337 go s _ = [text arr (s+off) (len-s)]
1338{-# INLINE [1] splitOn #-}
1340{-# RULES
1341"TEXT splitOn/singleton -> split/==" [~1] forall c t.
1342 splitOn (singleton c) t = split (==c) t
1343 #-}
1345-- | /O(n)/ Splits a 'Text' into components delimited by separators,
1346-- where the predicate returns True for a separator element. The
1347-- resulting components do not contain the separators. Two adjacent
1348-- separators result in an empty component in the output. eg.
1350-- > split (=='a') "aabbaca" == ["","","bb","c",""]
1351-- > split (=='a') "" == [""]
1352split :: (Char -> Bool) -> Text -> [Text]
1353split _ t@(Text _off _arr 0) = [t]
1354split p t = loop t
1355 where loop s | null s' = [l]
1356 | otherwise = l : loop (unsafeTail s')
1357 where (# l, s' #) = span_ (not . p) s
1358{-# INLINE split #-}
1360-- | /O(n)/ Splits a 'Text' into components of length @k@. The last
1361-- element may be shorter than the other chunks, depending on the
1362-- length of the input. Examples:
1364-- > chunksOf 3 "foobarbaz" == ["foo","bar","baz"]
1365-- > chunksOf 4 "haskell.org" == ["hask","ell.","org"]
1366chunksOf :: Int -> Text -> [Text]
1367chunksOf k = go
1368 where
1369 go t = case splitAt k t of
1370 (a,b) | null a -> []
1371 | otherwise -> a : go b
1372{-# INLINE chunksOf #-}
1374-- ----------------------------------------------------------------------------
1375-- * Searching
1377-------------------------------------------------------------------------------
1378-- ** Searching with a predicate
1380-- | /O(n)/ The 'find' function takes a predicate and a 'Text', and
1381-- returns the first element matching the predicate, or 'Nothing' if
1382-- there is no such element.
1383find :: (Char -> Bool) -> Text -> Maybe Char
1384find p t = S.findBy p (stream t)
1385{-# INLINE find #-}
1387-- | /O(n)/ The 'partition' function takes a predicate and a 'Text',
1388-- and returns the pair of 'Text's with elements which do and do not
1389-- satisfy the predicate, respectively; i.e.
1391-- > partition p t == (filter p t, filter (not . p) t)
1392partition :: (Char -> Bool) -> Text -> (Text, Text)
1393partition p t = (filter p t, filter (not . p) t)
1394{-# INLINE partition #-}
1396-- | /O(n)/ 'filter', applied to a predicate and a 'Text',
1397-- returns a 'Text' containing those characters that satisfy the
1398-- predicate.
1399filter :: (Char -> Bool) -> Text -> Text
1400filter p t = unstream (S.filter p (stream t))
1401{-# INLINE filter #-}
1403-- | /O(n+m)/ Find the first instance of @needle@ (which must be
1404-- non-'null') in @haystack@. The first element of the returned tuple
1405-- is the prefix of @haystack@ before @needle@ is matched. The second
1406-- is the remainder of @haystack@, starting with the match.
1408-- Examples:
1410-- > breakOn "::" "a::b::c" ==> ("a", "::b::c")
1411-- > breakOn "/" "foobar" ==> ("foobar", "")
1413-- Laws:
1415-- > append prefix match == haystack
1416-- > where (prefix, match) = breakOn needle haystack
1418-- If you need to break a string by a substring repeatedly (e.g. you
1419-- want to break on every instance of a substring), use 'breakOnAll'
1420-- instead, as it has lower startup overhead.
1422-- In (unlikely) bad cases, this function's time complexity degrades
1423-- towards /O(n*m)/.
1424breakOn :: Text -> Text -> (Text, Text)
1425breakOn pat src@(Text arr off len)
1426 | null pat = emptyError "breakOn"
1427 | otherwise = case indices pat src of
1428 [] -> (src, empty)
1429 (x:_) -> (text arr off x, text arr (off+x) (len-x))
1430{-# INLINE breakOn #-}
1432-- | /O(n+m)/ Similar to 'breakOn', but searches from the end of the
1433-- string.
1435-- The first element of the returned tuple is the prefix of @haystack@
1436-- up to and including the last match of @needle@. The second is the
1437-- remainder of @haystack@, following the match.
1439-- > breakOnEnd "::" "a::b::c" ==> ("a::b::", "c")
1440breakOnEnd :: Text -> Text -> (Text, Text)
1441breakOnEnd pat src = (reverse b, reverse a)
1442 where (a,b) = breakOn (reverse pat) (reverse src)
1443{-# INLINE breakOnEnd #-}
1445-- | /O(n+m)/ Find all non-overlapping instances of @needle@ in
1446-- @haystack@. Each element of the returned list consists of a pair:
1448-- * The entire string prior to the /k/th match (i.e. the prefix)
1450-- * The /k/th match, followed by the remainder of the string
1452-- Examples:
1454-- > breakOnAll "::" ""
1455-- > ==> []
1456-- > breakOnAll "/" "a/b/c/"
1457-- > ==> [("a", "/b/c/"), ("a/b", "/c/"), ("a/b/c", "/")]
1459-- In (unlikely) bad cases, this function's time complexity degrades
1460-- towards /O(n*m)/.
1462-- The @needle@ parameter may not be empty.
1463breakOnAll :: Text -- ^ @needle@ to search for
1464 -> Text -- ^ @haystack@ in which to search
1465 -> [(Text, Text)]
1466breakOnAll pat src@(Text arr off slen)
1467 | null pat = emptyError "breakOnAll"
1468 | otherwise = L.map step (indices pat src)
1469 where
1470 step x = (chunk 0 x, chunk x (slen-x))
1471 chunk !n !l = text arr (n+off) l
1472{-# INLINE breakOnAll #-}
1474-------------------------------------------------------------------------------
1475-- ** Indexing 'Text's
1477-- $index
1479-- If you think of a 'Text' value as an array of 'Char' values (which
1480-- it is not), you run the risk of writing inefficient code.
1482-- An idiom that is common in some languages is to find the numeric
1483-- offset of a character or substring, then use that number to split
1484-- or trim the searched string. With a 'Text' value, this approach
1485-- would require two /O(n)/ operations: one to perform the search, and
1486-- one to operate from wherever the search ended.
1488-- For example, suppose you have a string that you want to split on
1489-- the substring @\"::\"@, such as @\"foo::bar::quux\"@. Instead of
1490-- searching for the index of @\"::\"@ and taking the substrings
1491-- before and after that index, you would instead use @breakOnAll \"::\"@.
1493-- | /O(n)/ 'Text' index (subscript) operator, starting from 0.
1494index :: Text -> Int -> Char
1495index t n = S.index (stream t) n
1496{-# INLINE index #-}
1498-- | /O(n)/ The 'findIndex' function takes a predicate and a 'Text'
1499-- and returns the index of the first element in the 'Text' satisfying
1500-- the predicate. Subject to fusion.
1501findIndex :: (Char -> Bool) -> Text -> Maybe Int
1502findIndex p t = S.findIndex p (stream t)
1503{-# INLINE findIndex #-}
1505-- | /O(n+m)/ The 'count' function returns the number of times the
1506-- query string appears in the given 'Text'. An empty query string is
1507-- invalid, and will cause an error to be raised.
1509-- In (unlikely) bad cases, this function's time complexity degrades
1510-- towards /O(n*m)/.
1511count :: Text -> Text -> Int
1512count pat src
1513 | null pat = emptyError "count"
1514 | isSingleton pat = countChar (unsafeHead pat) src
1515 | otherwise = L.length (indices pat src)
1516{-# INLINE [1] count #-}
1518{-# RULES
1519"TEXT count/singleton -> countChar" [~1] forall c t.
1520 count (singleton c) t = countChar c t
1521 #-}
1523-- | /O(n)/ The 'countChar' function returns the number of times the
1524-- query element appears in the given 'Text'. Subject to fusion.
1525countChar :: Char -> Text -> Int
1526countChar c t = S.countChar c (stream t)
1527{-# INLINE countChar #-}
1529-------------------------------------------------------------------------------
1530-- * Zipping
1532-- | /O(n)/ 'zip' takes two 'Text's and returns a list of
1533-- corresponding pairs of bytes. If one input 'Text' is short,
1534-- excess elements of the longer 'Text' are discarded. This is
1535-- equivalent to a pair of 'unpack' operations.
1536zip :: Text -> Text -> [(Char,Char)]
1537zip a b = S.unstreamList $ S.zipWith (,) (stream a) (stream b)
1538{-# INLINE [0] zip #-}
1540-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
1541-- given as the first argument, instead of a tupling function.
1542-- Performs replacement on invalid scalar values.
1543zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
1544zipWith f t1 t2 = unstream (S.zipWith g (stream t1) (stream t2))
1545 where g a b = safe (f a b)
1546{-# INLINE [0] zipWith #-}
1548-- | /O(n)/ Breaks a 'Text' up into a list of words, delimited by 'Char's
1549-- representing white space.
1550words :: Text -> [Text]
1551words t@(Text arr off len) = loop 0 0
1552 where
1553 loop !start !n
1554 | n >= len = if start == n
1555 then []
1556 else [Text arr (start+off) (n-start)]
1557 | isSpace c =
1558 if start == n
1559 then loop (start+1) (start+1)
1560 else Text arr (start+off) (n-start) : loop (n+d) (n+d)
1561 | otherwise = loop start (n+d)
1562 where Iter c d = iter t n
1563{-# INLINE words #-}
1565-- | /O(n)/ Breaks a 'Text' up into a list of 'Text's at
1566-- newline 'Char's. The resulting strings do not contain newlines.
1567lines :: Text -> [Text]
1568lines ps | null ps = []
1569 | otherwise = h : if null t
1570 then []
1571 else lines (unsafeTail t)
1572 where (# h,t #) = span_ (/= '\n') ps
1573{-# INLINE lines #-}
1576-- | /O(n)/ Portably breaks a 'Text' up into a list of 'Text's at line
1577-- boundaries.
1579-- A line boundary is considered to be either a line feed, a carriage
1580-- return immediately followed by a line feed, or a carriage return.
1581-- This accounts for both Unix and Windows line ending conventions,
1582-- and for the old convention used on Mac OS 9 and earlier.
1583lines' :: Text -> [Text]
1584lines' ps | null ps = []
1585 | otherwise = h : case uncons t of
1586 Nothing -> []
1587 Just (c,t')
1588 | c == '\n' -> lines t'
1589 | c == '\r' -> case uncons t' of
1590 Just ('\n',t'') -> lines t''
1591 _ -> lines t'
1592 where (h,t) = span notEOL ps
1593 notEOL c = c /= '\n' && c /= '\r'
1594{-# INLINE lines' #-}
1597-- | /O(n)/ Joins lines, after appending a terminating newline to
1598-- each.
1599unlines :: [Text] -> Text
1600unlines = concat . L.map (`snoc` '\n')
1601{-# INLINE unlines #-}
1603-- | /O(n)/ Joins words using single space characters.
1604unwords :: [Text] -> Text
1605unwords = intercalate (singleton ' ')
1606{-# INLINE unwords #-}
1608-- | /O(n)/ The 'isPrefixOf' function takes two 'Text's and returns
1609-- 'True' iff the first is a prefix of the second. Subject to fusion.
1610isPrefixOf :: Text -> Text -> Bool
1611isPrefixOf a@(Text _ _ alen) b@(Text _ _ blen) =
1612 alen <= blen && S.isPrefixOf (stream a) (stream b)
1613{-# INLINE [1] isPrefixOf #-}
1615{-# RULES
1616"TEXT isPrefixOf -> fused" [~1] forall s t.
1617 isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
1618 #-}
1620-- | /O(n)/ The 'isSuffixOf' function takes two 'Text's and returns
1621-- 'True' iff the first is a suffix of the second.
1622isSuffixOf :: Text -> Text -> Bool
1623isSuffixOf a@(Text _aarr _aoff alen) b@(Text barr boff blen) =
1624 d >= 0 && a == b'
1625 where d = blen - alen
1626 b' | d == 0 = b
1627 | otherwise = Text barr (boff+d) alen
1628{-# INLINE isSuffixOf #-}
1630-- | /O(n+m)/ The 'isInfixOf' function takes two 'Text's and returns
1631-- 'True' iff the first is contained, wholly and intact, anywhere
1632-- within the second.
1634-- In (unlikely) bad cases, this function's time complexity degrades
1635-- towards /O(n*m)/.
1636isInfixOf :: Text -> Text -> Bool
1637isInfixOf needle haystack
1638 | null needle = True
1639 | isSingleton needle = S.elem (unsafeHead needle) . S.stream $ haystack
1640 | otherwise = not . L.null . indices needle $ haystack
1641{-# INLINE [1] isInfixOf #-}
1643{-# RULES
1644"TEXT isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1645 isInfixOf (singleton n) h = S.elem n (S.stream h)
1646 #-}
1648-------------------------------------------------------------------------------
1649-- * View patterns
1651-- | /O(n)/ Return the suffix of the second string if its prefix
1652-- matches the entire first string.
1654-- Examples:
1656-- > stripPrefix "foo" "foobar" == Just "bar"
1657-- > stripPrefix "" "baz" == Just "baz"
1658-- > stripPrefix "foo" "quux" == Nothing
1660-- This is particularly useful with the @ViewPatterns@ extension to
1661-- GHC, as follows:
1663-- > {-# LANGUAGE ViewPatterns #-}
1664-- > import Data.Text as T
1665-- >
1666-- > fnordLength :: Text -> Int
1667-- > fnordLength (stripPrefix "fnord" -> Just suf) = T.length suf
1668-- > fnordLength _ = -1
1669stripPrefix :: Text -> Text -> Maybe Text
1670stripPrefix p@(Text _arr _off plen) t@(Text arr off len)
1671 | p `isPrefixOf` t = Just $! text arr (off+plen) (len-plen)
1672 | otherwise = Nothing
1674-- | /O(n)/ Find the longest non-empty common prefix of two strings
1675-- and return it, along with the suffixes of each string at which they
1676-- no longer match.
1678-- If the strings do not have a common prefix or either one is empty,
1679-- this function returns 'Nothing'.
1681-- Examples:
1683-- > commonPrefixes "foobar" "fooquux" == Just ("foo","bar","quux")
1684-- > commonPrefixes "veeble" "fetzer" == Nothing
1685-- > commonPrefixes "" "baz" == Nothing
1686commonPrefixes :: Text -> Text -> Maybe (Text,Text,Text)
1687commonPrefixes t0@(Text arr0 off0 len0) t1@(Text arr1 off1 len1) = go 0 0
1688 where
1689 go !i !j | i < len0 && j < len1 && a == b = go (i+d0) (j+d1)
1690 | i > 0 = Just (Text arr0 off0 i,
1691 text arr0 (off0+i) (len0-i),
1692 text arr1 (off1+j) (len1-j))
1693 | otherwise = Nothing
1694 where Iter a d0 = iter t0 i
1695 Iter b d1 = iter t1 j
1697-- | /O(n)/ Return the prefix of the second string if its suffix
1698-- matches the entire first string.
1700-- Examples:
1702-- > stripSuffix "bar" "foobar" == Just "foo"
1703-- > stripSuffix "" "baz" == Just "baz"
1704-- > stripSuffix "foo" "quux" == Nothing
1706-- This is particularly useful with the @ViewPatterns@ extension to
1707-- GHC, as follows:
1709-- > {-# LANGUAGE ViewPatterns #-}
1710-- > import Data.Text as T
1711-- >
1712-- > quuxLength :: Text -> Int
1713-- > quuxLength (stripSuffix "quux" -> Just pre) = T.length pre
1714-- > quuxLength _ = -1
1715stripSuffix :: Text -> Text -> Maybe Text
1716stripSuffix p@(Text _arr _off plen) t@(Text arr off len)
1717 | p `isSuffixOf` t = Just $! text arr off (len-plen)
1718 | otherwise = Nothing
1720-- | Add a list of non-negative numbers. Errors out on overflow.
1721sumP :: String -> [Int] -> Int
1722sumP fun = go 0
1723 where go !a (x:xs)
1724 | ax >= 0 = go ax xs
1725 | otherwise = overflowError fun
1726 where ax = a + x
1727 go a _ = a
1729emptyError :: String -> a
1730emptyError fun = P.error $ "Data.Text." ++ fun ++ ": empty input"
1732overflowError :: String -> a
1733overflowError fun = P.error $ "Data.Text." ++ fun ++ ": size overflow"
1735-- | /O(n)/ Make a distinct copy of the given string, sharing no
1736-- storage with the original string.
1738-- As an example, suppose you read a large string, of which you need
1739-- only a small portion. If you do not use 'copy', the entire original
1740-- array will be kept alive in memory by the smaller string. Making a
1741-- copy \"breaks the link\" to the original array, allowing it to be
1742-- garbage collected if there are no other live references to it.
1743copy :: Text -> Text
1744copy (Text arr off len) = Text (A.run go) 0 len
1745 where
1746 go :: ST s (A.MArray s)
1747 go = do
1748 marr <- A.new len
1749 A.copyI marr 0 arr off len
1750 return marr