@@ -47,6 +47,7 @@ module Data.Text
4747 , init
4848 , null
4949 , length
50+ , compareLength
5051
5152 -- * Transformations
5253 , map
@@ -167,7 +168,7 @@ module Data.Text
167168 ) where
168169
169170import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
170− Eq(..), Ord(..), (++),
171+ Eq(..), Ord(..), Ordering(..), (++),
171172 Read(..), Show(..),
172173 (&&), (||), (+), (-), (.), ($), ($!), (>>), (*),
173174 div, error, not, return, otherwise)
@@ -414,6 +415,51 @@ length :: Text -> Int
414415length t = S.length (stream t)
415416{-# INLINE length #-}
416417
418+-- | /O(n)/ Compare the count of characters in a 'Text' to a number.
419+-- Subject to fusion.
420+--
421+-- This function gives the same answer as comparing against the result
422+-- of 'length', but can short circuit if the count of characters is
423+-- greater than the number, and hence be more efficient.
424+compareLength :: Text -> Int -> Ordering
425+compareLength t n = S.compareLengthI (stream t) n
426+{-# INLINE [1] compareLength #-}
427+
428+{-# RULES
429+"TEXT compareN/length -> compareLength" [~1] forall t n.
430+ compare (length t) n = compareLength t n
431+ #-}
432+
433+{-# RULES
434+"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
435+ (==) (length t) n = compareLength t n == EQ
436+ #-}
437+
438+{-# RULES
439+"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
440+ (/=) (length t) n = compareLength t n /= EQ
441+ #-}
442+
443+{-# RULES
444+"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
445+ (<) (length t) n = compareLength t n == LT
446+ #-}
447+
448+{-# RULES
449+"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
450+ (<=) (length t) n = compareLength t n /= GT
451+ #-}
452+
453+{-# RULES
454+"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
455+ (>) (length t) n = compareLength t n == GT
456+ #-}
457+
458+{-# RULES
459+"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
460+ (>=) (length t) n = compareLength t n /= LT
461+ #-}
462+
417463-- -----------------------------------------------------------------------------
418464-- * Transformations
419465-- | /O(n)/ 'map' @f@ @t@ is the 'Text' obtained by applying @f@ to
@@ -461,6 +507,12 @@ replace s d = intercalate d . split s
461507-- case conversion rules. As a result, these functions may map one
462508-- input character to two or three output characters. For examples,
463509-- see the documentation of each function.
510+--
511+-- /Note/: In some languages, case conversion is a locale- and
512+-- context-dependent operation. The case conversion functions in this
513+-- module are /not/ locale sensitive. Programs that require locale
514+-- sensitivity should use appropriate versions of the case mapping
515+-- functions from the @text-icu@ package.
464516
465517-- | /O(n)/ Convert a string to folded case. This function is mainly
466518-- useful for performing caseless (also known as case insensitive)