text 1.2.3.2 → 1.2.4.0
raw patch · 35 files changed
+368/−200 lines, 35 filesdep +bytestring-builderdep +template-haskelldep ~arraydep ~basedep ~binary
Dependencies added: bytestring-builder, template-haskell
Dependency ranges changed: array, base, binary, bytestring, deepseq, ghc-prim
Files
- Data/Text.hs +40/−35
- Data/Text/Array.hs +3/−3
- Data/Text/Encoding.hs +3/−3
- Data/Text/Foreign.hs +1/−1
- Data/Text/Internal/Functions.hs +0/−2
- Data/Text/Internal/Fusion/Common.hs +1/−1
- Data/Text/Internal/Fusion/Size.hs +1/−1
- Data/Text/Internal/IO.hs +1/−1
- Data/Text/Lazy.hs +34/−13
- Data/Text/Show.hs +1/−2
- benchmarks/haskell/Benchmarks.hs +30/−38
- benchmarks/haskell/Benchmarks/Builder.hs +2/−2
- benchmarks/haskell/Benchmarks/Concat.hs +2/−2
- benchmarks/haskell/Benchmarks/DecodeUtf8.hs +11/−4
- benchmarks/haskell/Benchmarks/EncodeUtf8.hs +3/−3
- benchmarks/haskell/Benchmarks/Equality.hs +11/−6
- benchmarks/haskell/Benchmarks/FileRead.hs +2/−2
- benchmarks/haskell/Benchmarks/FoldLines.hs +2/−2
- benchmarks/haskell/Benchmarks/Mul.hs +19/−11
- benchmarks/haskell/Benchmarks/Programs/BigTable.hs +2/−2
- benchmarks/haskell/Benchmarks/Programs/Cut.hs +2/−2
- benchmarks/haskell/Benchmarks/Programs/Fold.hs +2/−2
- benchmarks/haskell/Benchmarks/Programs/Sort.hs +2/−2
- benchmarks/haskell/Benchmarks/Programs/StripTags.hs +2/−2
- benchmarks/haskell/Benchmarks/Programs/Throughput.hs +2/−2
- benchmarks/haskell/Benchmarks/Pure.hs +36/−4
- benchmarks/haskell/Benchmarks/ReadNumbers.hs +11/−4
- benchmarks/haskell/Benchmarks/Replace.hs +10/−3
- benchmarks/haskell/Benchmarks/Search.hs +11/−4
- benchmarks/haskell/Benchmarks/Stream.hs +35/−21
- benchmarks/haskell/Benchmarks/WordFrequencies.hs +11/−4
- benchmarks/text-benchmarks.cabal +9/−1
- changelog.md +10/−3
- tests/text-tests.cabal +2/−1
- text.cabal +54/−11
Data/Text.hs view
@@ -1,10 +1,18 @@-{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types, UnboxedTuples #-}+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types, UnboxedTuples, TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-orphans #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif-#if __GLASGOW_HASKELL__ >= 708-{-# LANGUAGE TypeFamilies #-}+-- Using TemplateHaskell in text unconditionally is unacceptable, as+-- it's a GHC boot library. TemplateHaskellQuotes was added in 8.0, so+-- this would seem to be a problem. However, GHC's policy of only+-- needing to be able to compile itself from the last few releases+-- allows us to use full-fat TH on older versions, while using THQ for+-- GHC versions that may be used for bootstrapping.+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE TemplateHaskell #-} #endif -- |@@ -235,15 +243,18 @@ import qualified Data.Text.Internal.Functions as F import qualified Data.Text.Internal.Encoding.Utf16 as U16 import Data.Text.Internal.Search (indices)+import Data.Text.Internal.Unsafe.Shift (UnsafeShift(..)) #if defined(__HADDOCK__) import Data.ByteString (ByteString) import qualified Data.Text.Lazy as L import Data.Int (Int64) #endif import GHC.Base (eqInt, neInt, gtInt, geInt, ltInt, leInt)-#if __GLASGOW_HASKELL__ >= 708+#if MIN_VERSION_base(4,7,0) import qualified GHC.Exts as Exts #endif+import qualified Language.Haskell.TH.Lib as TH+import Language.Haskell.TH.Syntax (Lift, lift) #if MIN_VERSION_base(4,7,0) import Text.Printf (PrintfArg, formatArg, formatString) #endif@@ -371,7 +382,7 @@ instance IsString Text where fromString = pack -#if __GLASGOW_HASKELL__ >= 708+#if MIN_VERSION_base(4,7,0) -- | @since 1.2.0.0 instance Exts.IsList Text where type Item Text = Char@@ -413,6 +424,13 @@ _ -> P.error "gunfold" dataTypeOf _ = textDataType +-- | This instance has similar considerations to the 'Data' instance:+-- it preserves abstraction at the cost of inefficiency.+--+-- @since 1.2.4.0+instance Lift Text where+ lift = TH.appE (TH.varE 'pack) . TH.stringE . unpack+ #if MIN_VERSION_base(4,7,0) -- | Only defined for @base-4.7.0.0@ and later --@@ -605,7 +623,7 @@ -- Subject to fusion. length :: Text -> Int length t = S.length (stream t)-{-# INLINE [0] length #-}+{-# INLINE [1] length #-} -- length needs to be phased after the compareN/length rules otherwise -- it may inline before the rules have an opportunity to fire. @@ -702,7 +720,7 @@ -- >>> T.reverse "desrever" -- "reversed" ----- Subject to fusion.+-- Subject to fusion (fuses with its argument). reverse :: Text -> Text reverse t = S.reverse (stream t) {-# INLINE reverse #-}@@ -1033,8 +1051,7 @@ {-# INLINE scanl #-} -- | /O(n)/ 'scanl1' is a variant of 'scanl' that has no starting--- value argument. Subject to fusion. Performs replacement on--- invalid scalar values.+-- value argument. Performs replacement on invalid scalar values. -- -- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...] scanl1 :: (Char -> Char -> Char) -> Text -> Text@@ -1052,8 +1069,7 @@ {-# INLINE scanr #-} -- | /O(n)/ 'scanr1' is a variant of 'scanr' that has no starting--- value argument. Subject to fusion. Performs replacement on--- invalid scalar values.+-- value argument. Performs replacement on invalid scalar values. scanr1 :: (Char -> Char -> Char) -> Text -> Text scanr1 f t | null t = empty | otherwise = scanr f (last t) (init t)@@ -1091,16 +1107,19 @@ | isSingleton t = replicateChar n (unsafeHead t) | otherwise = Text (A.run x) 0 len where- len = l `mul` n+ len = l `mul` n -- TODO: detect overflows x :: ST s (A.MArray s) x = do arr <- A.new len- let loop !d !i | i >= n = return arr- | otherwise = let m = d + l- in A.copyI arr d a o m >> loop m (i+1)- loop 0 0+ A.copyI arr 0 a o l+ let loop !l1 =+ let rest = len - l1 in+ if rest <= l1 then A.copyM arr l1 arr 0 rest >> return arr+ else A.copyM arr l1 arr 0 l1 >> loop (l1 `shiftL` 1)+ loop l {-# INLINE [1] replicate #-} + {-# RULES "TEXT replicate/singleton -> replicateChar" [~1] forall n c. replicate n (singleton c) = replicateChar n c@@ -1237,7 +1256,7 @@ -- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text', -- returns the longest suffix (possibly empty) of elements that--- satisfy @p@. Subject to fusion.+-- satisfy @p@. -- Examples: -- -- >>> takeWhileEnd (=='o') "foo"@@ -1252,13 +1271,6 @@ where (c,d) = reverseIter t i {-# INLINE [1] takeWhileEnd #-} -{-# RULES-"TEXT takeWhileEnd -> fused" [~1] forall p t.- takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))-"TEXT takeWhileEnd -> unfused" [1] forall p t.- S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t- #-}- -- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after -- 'takeWhile' @p@ @t@. Subject to fusion. dropWhile :: (Char -> Bool) -> Text -> Text@@ -1278,7 +1290,7 @@ -- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after -- dropping characters that satisfy the predicate @p@ from the end of--- @t@. Subject to fusion.+-- @t@. -- -- Examples: --@@ -1292,13 +1304,6 @@ where (c,d) = reverseIter t i {-# INLINE [1] dropWhileEnd #-} -{-# RULES-"TEXT dropWhileEnd -> fused" [~1] forall p t.- dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))-"TEXT dropWhileEnd -> unfused" [1] forall p t.- S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t- #-}- -- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after -- dropping characters that satisfy the predicate @p@ from both the -- beginning and end of @t@. Subject to fusion.@@ -1311,7 +1316,7 @@ -- > dropWhile isSpace stripStart :: Text -> Text stripStart = dropWhile isSpace-{-# INLINE [1] stripStart #-}+{-# INLINE stripStart #-} -- | /O(n)/ Remove trailing white space from a string. Equivalent to: --@@ -1482,7 +1487,7 @@ -- | /O(n)/ The 'find' function takes a predicate and a 'Text', and -- returns the first element matching the predicate, or 'Nothing' if--- there is no such element.+-- there is no such element. Subject to fusion. find :: (Char -> Bool) -> Text -> Maybe Char find p t = S.findBy p (stream t) {-# INLINE find #-}@@ -1598,7 +1603,7 @@ -- searching for the index of @\"::\"@ and taking the substrings -- before and after that index, you would instead use @breakOnAll \"::\"@. --- | /O(n)/ 'Text' index (subscript) operator, starting from 0.+-- | /O(n)/ 'Text' index (subscript) operator, starting from 0. Subject to fusion. index :: Text -> Int -> Char index t n = S.index (stream t) n {-# INLINE index #-}
Data/Text/Array.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns, CPP, ForeignFunctionInterface, MagicHash, Rank2Types,+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types, RecordWildCards, UnboxedTuples, UnliftedFFITypes #-} {-# OPTIONS_GHC -fno-warn-unused-matches #-} -- |@@ -58,7 +58,7 @@ #if defined(ASSERTS) import Control.Exception (assert) #endif-#if __GLASGOW_HASKELL__ >= 702+#if MIN_VERSION_base(4,4,0) import Control.Monad.ST.Unsafe (unsafeIOToST) #else import Control.Monad.ST (unsafeIOToST)@@ -66,7 +66,7 @@ import Data.Bits ((.&.), xor) import Data.Text.Internal.Unsafe (inlinePerformIO) import Data.Text.Internal.Unsafe.Shift (shiftL, shiftR)-#if __GLASGOW_HASKELL__ >= 703+#if MIN_VERSION_base(4,5,0) import Foreign.C.Types (CInt(CInt), CSize(CSize)) #else import Foreign.C.Types (CInt, CSize)
Data/Text/Encoding.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns, CPP, ForeignFunctionInterface, GeneralizedNewtypeDeriving, MagicHash,+{-# LANGUAGE BangPatterns, CPP, GeneralizedNewtypeDeriving, MagicHash, UnliftedFFITypes #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-}@@ -59,7 +59,7 @@ , encodeUtf8BuilderEscaped ) where -#if __GLASGOW_HASKELL__ >= 702+#if MIN_VERSION_base(4,4,0) import Control.Monad.ST.Unsafe (unsafeIOToST, unsafeSTToIO) #else import Control.Monad.ST (unsafeIOToST, unsafeSTToIO)@@ -78,7 +78,7 @@ import Data.Text.Show () import Data.Text.Unsafe (unsafeDupablePerformIO) import Data.Word (Word8, Word32)-#if __GLASGOW_HASKELL__ >= 703+#if MIN_VERSION_base(4,5,0) import Foreign.C.Types (CSize(CSize)) #else import Foreign.C.Types (CSize)
Data/Text/Foreign.hs view
@@ -34,7 +34,7 @@ #if defined(ASSERTS) import Control.Exception (assert) #endif-#if __GLASGOW_HASKELL__ >= 702+#if MIN_VERSION_base(4,4,0) import Control.Monad.ST.Unsafe (unsafeIOToST) #else import Control.Monad.ST (unsafeIOToST)
Data/Text/Internal/Functions.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE CPP, DeriveDataTypeable #-}- -- | -- Module : Data.Text.Internal.Functions -- Copyright : 2010 Bryan O'Sullivan
Data/Text/Internal/Fusion/Common.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE PatternGuards, BangPatterns, MagicHash, Rank2Types #-}+{-# LANGUAGE BangPatterns, MagicHash, Rank2Types #-} -- | -- Module : Data.Text.Internal.Fusion.Common -- Copyright : (c) Bryan O'Sullivan 2009, 2012
Data/Text/Internal/Fusion/Size.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, PatternGuards #-}+{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-missing-methods #-} -- | -- Module : Data.Text.Internal.Fusion.Internal
Data/Text/Internal/IO.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns, CPP, RecordWildCards #-}+{-# LANGUAGE BangPatterns, RecordWildCards #-} -- | -- Module : Data.Text.Internal.IO -- Copyright : (c) 2009, 2010 Bryan O'Sullivan,
Data/Text/Lazy.hs view
@@ -1,10 +1,18 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE BangPatterns, MagicHash, CPP #-}+{-# LANGUAGE BangPatterns, MagicHash, CPP, TypeFamilies #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif-#if __GLASGOW_HASKELL__ >= 708-{-# LANGUAGE TypeFamilies #-}+-- Using TemplateHaskell in text unconditionally is unacceptable, as+-- it's a GHC boot library. TemplateHaskellQuotes was added in 8.0, so+-- this would seem to be a problem. However, GHC's policy of only+-- needing to be able to compile itself from the last few releases+-- allows us to use full-fat TH on older versions, while using THQ for+-- GHC versions that may be used for bootstrapping.+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE TemplateHaskell #-} #endif -- |@@ -235,10 +243,12 @@ #else import qualified GHC.Base as GHC #endif-#if __GLASGOW_HASKELL__ >= 708+#if MIN_VERSION_base(4,7,0) import qualified GHC.Exts as Exts #endif import GHC.Prim (Addr#)+import qualified Language.Haskell.TH.Lib as TH+import Language.Haskell.TH.Syntax (Lift, lift) #if MIN_VERSION_base(4,7,0) import Text.Printf (PrintfArg, formatArg, formatString) #endif@@ -365,7 +375,7 @@ instance IsString Text where fromString = pack -#if __GLASGOW_HASKELL__ >= 708+#if MIN_VERSION_base(4,7,0) -- | @since 1.2.0.0 instance Exts.IsList Text where type Item Text = Char@@ -399,6 +409,13 @@ _ -> error "Data.Text.Lazy.Text.gunfold" dataTypeOf _ = textDataType +-- | This instance has similar considerations to the 'Data' instance:+-- it preserves abstraction at the cost of inefficiency.+--+-- @since 1.2.4.0+instance Lift Text where+ lift = TH.appE (TH.varE 'pack) . TH.stringE . unpack+ #if MIN_VERSION_base(4,7,0) -- | Only defined for @base-4.7.0.0@ and later --@@ -793,7 +810,7 @@ -- itself. toCaseFold :: Text -> Text toCaseFold t = unstream (S.toCaseFold (stream t))-{-# INLINE [0] toCaseFold #-}+{-# INLINE toCaseFold #-} -- | /O(n)/ Convert a string to lower case, using simple case -- conversion. Subject to fusion.@@ -936,8 +953,7 @@ {-# INLINE scanl #-} -- | /O(n)/ 'scanl1' is a variant of 'scanl' that has no starting--- value argument. Subject to fusion. Performs replacement on--- invalid scalar values.+-- value argument. Performs replacement on invalid scalar values. -- -- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...] scanl1 :: (Char -> Char -> Char) -> Text -> Text@@ -1034,6 +1050,8 @@ {-# RULES "LAZY TEXT replicate/singleton -> replicateChar" [~1] forall n c. replicate n (singleton c) = replicateChar n c+"LAZY TEXT replicate/unstream/singleton -> replicateChar" [~1] forall n c.+ replicate n (unstream (S.singleton c)) = replicateChar n c #-} -- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'@@ -1041,8 +1059,9 @@ -- 'Text' from a seed value. The function takes the element and -- returns 'Nothing' if it is done producing the 'Text', otherwise -- 'Just' @(a,b)@. In this case, @a@ is the next 'Char' in the--- string, and @b@ is the seed value for further production. Performs--- replacement on invalid scalar values.+-- string, and @b@ is the seed value for further production.+-- Subject to fusion.+-- Performs replacement on invalid scalar values. unfoldr :: (a -> Maybe (Char,a)) -> a -> Text unfoldr f s = unstream (S.unfoldr (firstf safe . f) s) {-# INLINE unfoldr #-}@@ -1052,6 +1071,7 @@ -- first argument to 'unfoldrN'. This function is more efficient than -- 'unfoldr' when the maximum length of the result is known and -- correct, otherwise its performance is similar to 'unfoldr'.+-- Subject to fusion. -- Performs replacement on invalid scalar values. unfoldrN :: Int64 -> (a -> Maybe (Char,a)) -> a -> Text unfoldrN n f s = unstream (S.unfoldrN n (firstf safe . f) s)@@ -1228,7 +1248,7 @@ -- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after -- dropping characters that satisfy the predicate @p@ from both the--- beginning and end of @t@. Subject to fusion.+-- beginning and end of @t@. dropAround :: (Char -> Bool) -> Text -> Text dropAround p = dropWhile p . dropWhileEnd p {-# INLINE [1] dropAround #-}@@ -1238,7 +1258,7 @@ -- > dropWhile isSpace stripStart :: Text -> Text stripStart = dropWhile isSpace-{-# INLINE [1] stripStart #-}+{-# INLINE stripStart #-} -- | /O(n)/ Remove trailing white space from a string. Equivalent to: --@@ -1656,7 +1676,7 @@ -- | /O(n)/ The 'find' function takes a predicate and a 'Text', and -- returns the first element in matching the predicate, or 'Nothing'--- if there is no such element.+-- if there is no such element. Subject to fusion. find :: (Char -> Bool) -> Text -> Maybe Char find p t = S.findBy p (stream t) {-# INLINE find #-}@@ -1671,6 +1691,7 @@ {-# INLINE partition #-} -- | /O(n)/ 'Text' index (subscript) operator, starting from 0.+-- Subject to fusion. index :: Text -> Int64 -> Char index t n = S.index (stream t) n {-# INLINE index #-}
Data/Text/Show.hs view
@@ -42,8 +42,7 @@ unpack = S.unstreamList . stream {-# INLINE [1] unpack #-} --- | /O(n)/ Convert a literal string into a 'Text'. Subject to--- fusion.+-- | /O(n)/ Convert a literal string into a 'Text'. -- -- This is exposed solely for people writing GHC rewrite rules. --
benchmarks/haskell/Benchmarks.hs view
@@ -5,7 +5,7 @@ ( main ) where -import Criterion.Main (Benchmark, defaultMain, bgroup)+import Criterion.Main (defaultMain, bgroup, env) import System.FilePath ((</>)) import System.IO (IOMode (WriteMode), openFile, hSetEncoding, utf8) @@ -32,50 +32,42 @@ import qualified Benchmarks.Programs.Throughput as Programs.Throughput main :: IO ()-main = benchmarks >>= defaultMain--benchmarks :: IO [Benchmark]-benchmarks = do+main = do sink <- openFile "/dev/null" WriteMode hSetEncoding sink utf8-- -- Traditional benchmarks- bs <- sequence+ defaultMain [ Builder.benchmark , Concat.benchmark- , DecodeUtf8.benchmark "html" (tf "libya-chinese.html")- , DecodeUtf8.benchmark "xml" (tf "yiwiki.xml")- , DecodeUtf8.benchmark "ascii" (tf "ascii.txt")- , DecodeUtf8.benchmark "russian" (tf "russian.txt")- , DecodeUtf8.benchmark "japanese" (tf "japanese.txt")+ , env (DecodeUtf8.initEnv (tf "libya-chinese.html")) (DecodeUtf8.benchmark "html")+ , env (DecodeUtf8.initEnv (tf "yiwiki.xml")) (DecodeUtf8.benchmark "xml")+ , env (DecodeUtf8.initEnv (tf "ascii.txt")) (DecodeUtf8.benchmark "ascii")+ , env (DecodeUtf8.initEnv (tf "russian.txt")) (DecodeUtf8.benchmark "russian")+ , env (DecodeUtf8.initEnv (tf "japanese.txt")) (DecodeUtf8.benchmark "japanese") , EncodeUtf8.benchmark "επανάληψη 竺法蘭共譯"- , Equality.benchmark (tf "japanese.txt")+ , env (Equality.initEnv (tf "japanese.txt")) Equality.benchmark , FileRead.benchmark (tf "russian.txt") , FoldLines.benchmark (tf "russian.txt")- , Mul.benchmark- , Pure.benchmark "tiny" (tf "tiny.txt")- , Pure.benchmark "ascii" (tf "ascii-small.txt")- -- , Pure.benchmark "france" (tf "france.html")- , Pure.benchmark "russian" (tf "russian-small.txt")- , Pure.benchmark "japanese" (tf "japanese.txt")- , ReadNumbers.benchmark (tf "numbers.txt")- , Replace.benchmark (tf "russian.txt") "принимая" "своем"- , Search.benchmark (tf "russian.txt") "принимая"- , Stream.benchmark (tf "russian.txt")- , WordFrequencies.benchmark (tf "russian.txt")- ]-- -- Program-like benchmarks- ps <- bgroup "Programs" `fmap` sequence- [ Programs.BigTable.benchmark sink- , Programs.Cut.benchmark (tf "russian.txt") sink 20 40- , Programs.Fold.benchmark (tf "russian.txt") sink- , Programs.Sort.benchmark (tf "russian.txt") sink- , Programs.StripTags.benchmark (tf "yiwiki.xml") sink- , Programs.Throughput.benchmark (tf "russian.txt") sink+ , env Mul.initEnv Mul.benchmark+ , env (Pure.initEnv (tf "tiny.txt")) (Pure.benchmark "tiny")+ , env (Pure.initEnv (tf "ascii-small.txt")) (Pure.benchmark "ascii-small")+ , env (Pure.initEnv (tf "ascii.txt")) (Pure.benchmark "ascii")+ , env (Pure.initEnv (tf "english.txt")) (Pure.benchmark "english")+ , env (Pure.initEnv (tf "russian-small.txt")) (Pure.benchmark "russian")+ , env (Pure.initEnv (tf "japanese.txt")) (Pure.benchmark "japanese")+ , env (ReadNumbers.initEnv (tf "numbers.txt")) ReadNumbers.benchmark+ , env (Replace.initEnv (tf "russian.txt")) (Replace.benchmark "принимая" "своем")+ , env (Search.initEnv (tf "russian.txt")) (Search.benchmark "принимая")+ , env (Stream.initEnv (tf "russian.txt")) Stream.benchmark+ , env (WordFrequencies.initEnv (tf "russian.txt")) WordFrequencies.benchmark+ , bgroup "Programs"+ [ Programs.BigTable.benchmark sink+ , Programs.Cut.benchmark (tf "russian.txt") sink 20 40+ , Programs.Fold.benchmark (tf "russian.txt") sink+ , Programs.Sort.benchmark (tf "russian.txt") sink+ , Programs.StripTags.benchmark (tf "yiwiki.xml") sink+ , Programs.Throughput.benchmark (tf "russian.txt") sink+ ] ]-- return $ bs ++ [ps]- where+ where -- Location of a test file tf = ("../tests/text-test-data" </>)
benchmarks/haskell/Benchmarks/Builder.hs view
@@ -23,8 +23,8 @@ import qualified Data.Text.Lazy.Builder.Int as Int import Data.Int (Int64) -benchmark :: IO Benchmark-benchmark = return $ bgroup "Builder"+benchmark :: Benchmark+benchmark = bgroup "Builder" [ bgroup "Comparison" [ bench "LazyText" $ nf (LT.length . LTB.toLazyText . mconcat . map LTB.fromText) texts
benchmarks/haskell/Benchmarks/Concat.hs view
@@ -6,8 +6,8 @@ import Criterion (Benchmark, bgroup, bench, whnf) import Data.Text as T -benchmark :: IO Benchmark-benchmark = return $ bgroup "Concat"+benchmark :: Benchmark+benchmark = bgroup "Concat" [ bench "append" $ whnf (append4 "Text 1" "Text 2" "Text 3") "Text 4" , bench "concat" $ whnf (concat4 "Text 1" "Text 2" "Text 3") "Text 4" , bench "write" $ whnf (write4 "Text 1" "Text 2" "Text 3") "Text 4"
benchmarks/haskell/Benchmarks/DecodeUtf8.hs view
@@ -15,7 +15,8 @@ -- The latter are used for testing stream fusion. -- module Benchmarks.DecodeUtf8- ( benchmark+ ( initEnv+ , benchmark ) where import Foreign.C.Types@@ -34,10 +35,16 @@ import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Encoding as TL -benchmark :: String -> FilePath -> IO Benchmark-benchmark kind fp = do+type Env = (B.ByteString, BL.ByteString)++initEnv :: FilePath -> IO Env+initEnv fp = do bs <- B.readFile fp lbs <- BL.readFile fp+ return (bs, lbs)++benchmark :: String -> Env -> Benchmark+benchmark kind ~(bs, lbs) = let bench name = C.bench (name ++ "+" ++ kind) decodeStream (Chunk b0 bs0) = case T.streamDecodeUtf8 b0 of T.Some t0 _ f0 -> t0 : go f0 bs0@@ -45,7 +52,7 @@ T.Some t1 _ f1 -> t1 : go f1 bs1 go _ _ = [] decodeStream _ = []- return $ bgroup "DecodeUtf8"+ in bgroup "DecodeUtf8" [ bench "Strict" $ nf T.decodeUtf8 bs , bench "Stream" $ nf decodeStream lbs , bench "IConv" $ whnfIO $ iconv bs
benchmarks/haskell/Benchmarks/EncodeUtf8.hs view
@@ -18,9 +18,9 @@ import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Encoding as TL -benchmark :: String -> IO Benchmark-benchmark string = do- return $ bgroup "EncodeUtf8"+benchmark :: String -> Benchmark+benchmark string =+ bgroup "EncodeUtf8" [ bench "Text" $ whnf (B.length . T.encodeUtf8) text , bench "LazyText" $ whnf (BL.length . TL.encodeUtf8) lazyText ]
benchmarks/haskell/Benchmarks/Equality.hs view
@@ -6,7 +6,8 @@ -- * Comparison of strings (Eq instance) -- module Benchmarks.Equality- ( benchmark+ ( initEnv+ , benchmark ) where import Criterion (Benchmark, bgroup, bench, whnf)@@ -17,8 +18,10 @@ import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Encoding as TL -benchmark :: FilePath -> IO Benchmark-benchmark fp = do+type Env = (T.Text, TL.Text, B.ByteString, BL.ByteString, BL.ByteString, String)++initEnv :: FilePath -> IO Env+initEnv fp = do b <- B.readFile fp bl1 <- BL.readFile fp -- A lazy bytestring is a list of chunks. When we do not explicitly create two@@ -27,9 +30,11 @@ -- we read the lazy bytestring twice here. bl2 <- BL.readFile fp l <- readFile fp- let t = T.decodeUtf8 b- tl = TL.decodeUtf8 bl1- return $ bgroup "Equality"+ return (T.decodeUtf8 b, TL.decodeUtf8 bl1, b, bl1, bl2, l)++benchmark :: Env -> Benchmark+benchmark ~(t, tl, b, bl1, bl2, l) =+ bgroup "Equality" [ bench "Text" $ whnf (== T.init t `T.snoc` '\xfffd') t , bench "LazyText" $ whnf (== TL.init tl `TL.snoc` '\xfffd') tl , bench "ByteString" $ whnf (== B.init b `B.snoc` '\xfffd') b
benchmarks/haskell/Benchmarks/FileRead.hs view
@@ -19,8 +19,8 @@ import qualified Data.Text.Lazy.Encoding as LT import qualified Data.Text.Lazy.IO as LT -benchmark :: FilePath -> IO Benchmark-benchmark p = return $ bgroup "FileRead"+benchmark :: FilePath -> Benchmark+benchmark p = bgroup "FileRead" [ bench "String" $ whnfIO $ length <$> readFile p , bench "ByteString" $ whnfIO $ SB.length <$> SB.readFile p , bench "LazyByteString" $ whnfIO $ LB.length <$> LB.readFile p
benchmarks/haskell/Benchmarks/FoldLines.hs view
@@ -16,8 +16,8 @@ import qualified Data.Text as T import qualified Data.Text.IO as T -benchmark :: FilePath -> IO Benchmark-benchmark fp = return $ bgroup "ReadLines"+benchmark :: FilePath -> Benchmark+benchmark fp = bgroup "ReadLines" [ bench "Text" $ withHandle $ foldLinesT (\n _ -> n + 1) (0 :: Int) , bench "ByteString" $ withHandle $ foldLinesB (\n _ -> n + 1) (0 :: Int) ]
benchmarks/haskell/Benchmarks/Mul.hs view
@@ -1,4 +1,7 @@-module Benchmarks.Mul (benchmark) where+module Benchmarks.Mul+ ( initEnv+ , benchmark+ ) where import Control.Exception (evaluate) import Criterion.Main@@ -12,16 +15,21 @@ | m <= maxBound `quot` n = m * n | otherwise = error "overflow" -benchmark :: IO Benchmark-benchmark = do- _ <- evaluate testVector32- _ <- evaluate testVector64- return $ bgroup "Mul" [- bench "oldMul" $ whnf (U.map (uncurry oldMul)) testVector64- , bench "mul64" $ whnf (U.map (uncurry mul64)) testVector64- , bench "*64" $ whnf (U.map (uncurry (*))) testVector64- , bench "mul32" $ whnf (U.map (uncurry mul32)) testVector32- , bench "*32" $ whnf (U.map (uncurry (*))) testVector32+type Env = (U.Vector (Int32,Int32), U.Vector (Int64,Int64))++initEnv :: IO Env+initEnv = do+ x <- evaluate testVector32+ y <- evaluate testVector64+ return (x, y)++benchmark :: Env -> Benchmark+benchmark ~(tv32, tv64) = bgroup "Mul"+ [ bench "oldMul" $ whnf (U.map (uncurry oldMul)) tv64+ , bench "mul64" $ whnf (U.map (uncurry mul64)) tv64+ , bench "*64" $ whnf (U.map (uncurry (*))) tv64+ , bench "mul32" $ whnf (U.map (uncurry mul32)) tv32+ , bench "*32" $ whnf (U.map (uncurry (*))) tv32 ] testVector64 :: U.Vector (Int64,Int64)
benchmarks/haskell/Benchmarks/Programs/BigTable.hs view
@@ -18,8 +18,8 @@ import System.IO (Handle) import qualified Data.Text as T -benchmark :: Handle -> IO Benchmark-benchmark sink = return $ bench "BigTable" $ whnfIO $ do+benchmark :: Handle -> Benchmark+benchmark sink = bench "BigTable" $ whnfIO $ do hPutStr sink "Content-Type: text/html\n\n<table>" hPutStr sink . toLazyText . makeTable =<< rows hPutStr sink "</table>"
benchmarks/haskell/Benchmarks/Programs/Cut.hs view
@@ -29,8 +29,8 @@ import qualified Data.Text.Lazy.Encoding as TL import qualified Data.Text.Lazy.IO as TL -benchmark :: FilePath -> Handle -> Int -> Int -> IO Benchmark-benchmark p sink from to = return $ bgroup "Cut"+benchmark :: FilePath -> Handle -> Int -> Int -> Benchmark+benchmark p sink from to = bgroup "Cut" [ bench' "String" string , bench' "ByteString" byteString , bench' "LazyByteString" lazyByteString
benchmarks/haskell/Benchmarks/Programs/Fold.hs view
@@ -28,8 +28,8 @@ import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.IO as TL -benchmark :: FilePath -> Handle -> IO Benchmark-benchmark i o = return $+benchmark :: FilePath -> Handle -> Benchmark+benchmark i o = bench "Fold" $ whnfIO $ T.readFile i >>= TL.hPutStr o . fold 80 -- | We represent a paragraph by a word list
benchmarks/haskell/Benchmarks/Programs/Sort.hs view
@@ -33,8 +33,8 @@ import qualified Data.Text.Lazy.Encoding as TL import qualified Data.Text.Lazy.IO as TL -benchmark :: FilePath -> Handle -> IO Benchmark-benchmark i o = return $ bgroup "Sort"+benchmark :: FilePath -> Handle -> Benchmark+benchmark i o = bgroup "Sort" [ bench "String" $ whnfIO $ readFile i >>= hPutStr o . string , bench "ByteString" $ whnfIO $ B.readFile i >>= B.hPutStr o . byteString , bench "LazyByteString" $ whnfIO $
benchmarks/haskell/Benchmarks/Programs/StripTags.hs view
@@ -24,8 +24,8 @@ import qualified Data.Text.Encoding as T import qualified Data.Text.IO as T -benchmark :: FilePath -> Handle -> IO Benchmark-benchmark i o = return $ bgroup "StripTags"+benchmark :: FilePath -> Handle -> Benchmark+benchmark i o = bgroup "StripTags" [ bench "String" $ whnfIO $ readFile i >>= hPutStr o . string , bench "ByteString" $ whnfIO $ B.readFile i >>= B.hPutStr o . byteString , bench "Text" $ whnfIO $ T.readFile i >>= T.hPutStr o . text
benchmarks/haskell/Benchmarks/Programs/Throughput.hs view
@@ -27,8 +27,8 @@ import qualified Data.Text.Lazy.Encoding as TL import qualified Data.Text.Lazy.IO as TL -benchmark :: FilePath -> Handle -> IO Benchmark-benchmark fp sink = return $ bgroup "Throughput"+benchmark :: FilePath -> Handle -> Benchmark+benchmark fp sink = bgroup "Throughput" [ bench "String" $ whnfIO $ readFile fp >>= hPutStr sink , bench "ByteString" $ whnfIO $ B.readFile fp >>= B.hPutStr sink , bench "LazyByteString" $ whnfIO $ BL.readFile fp >>= BL.hPutStr sink
benchmarks/haskell/Benchmarks/Pure.hs view
@@ -5,9 +5,11 @@ -- * Most pure functions defined the string types -- {-# LANGUAGE BangPatterns, CPP, GADTs, MagicHash #-}+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, RecordWildCards #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Benchmarks.Pure- ( benchmark+ ( initEnv+ , benchmark ) where import Control.DeepSeq (NFData (..))@@ -16,6 +18,8 @@ import Data.Char (toLower, toUpper) import Data.Monoid (mappend, mempty) import GHC.Base (Char (..), Int (..), chr#, ord#, (+#))+import GHC.Generics (Generic)+import GHC.Int (Int64) import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.ByteString.UTF8 as UTF8@@ -26,8 +30,32 @@ import qualified Data.Text.Lazy.Builder as TB import qualified Data.Text.Lazy.Encoding as TL -benchmark :: String -> FilePath -> IO Benchmark-benchmark kind fp = do+data Env = Env+ { bsa :: !BS.ByteString+ , ta :: !T.Text+ , tb :: !T.Text+ , tla :: !TL.Text+ , tlb :: !TL.Text+ , bsb :: !BS.ByteString+ , bla :: !BL.ByteString+ , blb :: !BL.ByteString+ , sa :: !String+ , sb :: !String+ , bsa_len :: !Int+ , ta_len :: !Int+ , bla_len :: !Int64+ , tla_len :: !Int64+ , sa_len :: !Int+ , bsl :: [BS.ByteString]+ , bll :: [BL.ByteString]+ , tl :: [T.Text]+ , tll :: [TL.Text]+ , sl :: [String]+ } deriving (Generic, NFData)+++initEnv :: FilePath -> IO Env+initEnv fp = do -- Evaluate stuff before actually running the benchmark, we don't want to -- count it here. @@ -63,7 +91,11 @@ tll <- evaluate $ TL.lines tla sl <- evaluate $ L.lines sa - return $ bgroup "Pure"+ return Env{..}++benchmark :: String -> Env -> Benchmark+benchmark kind ~Env{..} =+ bgroup "Pure" [ bgroup "append" [ benchT $ nf (T.append tb) ta , benchTL $ nf (TL.append tlb) tla
benchmarks/haskell/Benchmarks/ReadNumbers.hs view
@@ -17,7 +17,8 @@ -- * Lexing/parsing of different numerical types -- module Benchmarks.ReadNumbers- ( benchmark+ ( initEnv+ , benchmark ) where import Criterion (Benchmark, bgroup, bench, whnf)@@ -33,8 +34,10 @@ import qualified Data.Text.Lazy.Read as TL import qualified Data.Text.Read as T -benchmark :: FilePath -> IO Benchmark-benchmark fp = do+type Env = ([String], [T.Text], [TL.Text], [B.ByteString], [BL.ByteString])++initEnv :: FilePath -> IO Env+initEnv fp = do -- Read all files into lines: string, text, lazy text, bytestring, lazy -- bytestring s <- lines `fmap` readFile fp@@ -42,7 +45,11 @@ tl <- TL.lines `fmap` TL.readFile fp b <- B.lines `fmap` B.readFile fp bl <- BL.lines `fmap` BL.readFile fp- return $ bgroup "ReadNumbers"+ return (s, t, tl, b, bl)++benchmark :: Env -> Benchmark+benchmark ~(s, t, tl, b, bl) =+ bgroup "ReadNumbers" [ bench "DecimalString" $ whnf (int . string readDec) s , bench "HexadecimalString" $ whnf (int . string readHex) s , bench "DoubleString" $ whnf (double . string readFloat) s
benchmarks/haskell/Benchmarks/Replace.hs view
@@ -7,6 +7,7 @@ -- module Benchmarks.Replace ( benchmark+ , initEnv ) where import Criterion (Benchmark, bgroup, bench, nf)@@ -20,13 +21,19 @@ import qualified Data.Text.Lazy.Encoding as TL import qualified Data.Text.Lazy.IO as TL -benchmark :: FilePath -> String -> String -> IO Benchmark-benchmark fp pat sub = do+type Env = (T.Text, B.ByteString, TL.Text, BL.ByteString)++initEnv :: FilePath -> IO Env+initEnv fp = do tl <- TL.readFile fp bl <- BL.readFile fp let !t = TL.toStrict tl !b = T.encodeUtf8 t- return $ bgroup "Replace" [+ return (t, b, tl, bl)++benchmark :: String -> String -> Env -> Benchmark+benchmark pat sub ~(t, b, tl, bl) =+ bgroup "Replace" [ bench "Text" $ nf (T.length . T.replace tpat tsub) t , bench "ByteString" $ nf (BL.length . B.replace bpat bsub) b , bench "LazyText" $ nf (TL.length . TL.replace tlpat tlsub) tl
benchmarks/haskell/Benchmarks/Search.hs view
@@ -5,7 +5,8 @@ -- * Searching all occurences of a pattern using library routines -- module Benchmarks.Search- ( benchmark+ ( initEnv+ , benchmark ) where import Criterion (Benchmark, bench, bgroup, whnf)@@ -19,13 +20,19 @@ import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.IO as TL -benchmark :: FilePath -> T.Text -> IO Benchmark-benchmark fp needleT = do+type Env = (B.ByteString, BL.ByteString, T.Text, TL.Text)++initEnv :: FilePath -> IO Env+initEnv fp = do b <- B.readFile fp bl <- BL.readFile fp t <- T.readFile fp tl <- TL.readFile fp- return $ bgroup "FileIndices"+ return (b, bl, t, tl)++benchmark :: T.Text -> Env -> Benchmark+benchmark needleT ~(b, bl, t, tl) =+ bgroup "FileIndices" [ bench "ByteString" $ whnf (byteString needleB) b , bench "LazyByteString" $ whnf (lazyByteString needleB) bl , bench "Text" $ whnf (text needleT) t
benchmarks/haskell/Benchmarks/Stream.hs view
@@ -6,24 +6,31 @@ -- * Most streaming functions -- {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, RecordWildCards #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Benchmarks.Stream- ( benchmark+ ( initEnv+ , benchmark ) where import Control.DeepSeq (NFData (..)) import Criterion (Benchmark, bgroup, bench, nf)+import qualified Data.Text as T+import qualified Data.ByteString as B+import qualified Data.Text.Lazy as TL+import qualified Data.ByteString.Lazy as BL import Data.Text.Internal.Fusion.Types (Step (..), Stream (..)) import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding.Error as E import qualified Data.Text.Internal.Encoding.Fusion as T import qualified Data.Text.Internal.Encoding.Fusion.Common as F-import qualified Data.Text.Internal.Fusion as F+import qualified Data.Text.Internal.Fusion as T import qualified Data.Text.IO as T import qualified Data.Text.Lazy.Encoding as TL import qualified Data.Text.Internal.Lazy.Encoding.Fusion as TL-import qualified Data.Text.Internal.Lazy.Fusion as FL+import qualified Data.Text.Internal.Lazy.Fusion as TL import qualified Data.Text.Lazy.IO as TL+import GHC.Generics (Generic) instance NFData a => NFData (Stream a) where -- Currently, this implementation does not force evaluation of the size hint@@ -34,8 +41,24 @@ Skip s' -> go s' Yield x s' -> rnf x `seq` go s' -benchmark :: FilePath -> IO Benchmark-benchmark fp = do+data Env = Env+ { t :: !T.Text+ , utf8 :: !B.ByteString+ , utf16le :: !B.ByteString+ , utf16be :: !B.ByteString+ , utf32le :: !B.ByteString+ , utf32be :: !B.ByteString+ , tl :: !TL.Text+ , utf8L :: !BL.ByteString+ , utf16leL :: !BL.ByteString+ , utf16beL :: !BL.ByteString+ , utf32leL :: !BL.ByteString+ , utf32beL :: !BL.ByteString+ , s :: T.Stream Char+ } deriving (Generic, NFData)++initEnv :: FilePath -> IO Env+initEnv fp = do -- Different formats t <- T.readFile fp let !utf8 = T.encodeUtf8 t@@ -53,25 +76,16 @@ !utf32beL = TL.encodeUtf32BE tl -- For the functions which operate on streams- let !s = F.stream t-- return $ bgroup "Stream"+ let !s = T.stream t+ return Env{..} +benchmark :: Env -> Benchmark+benchmark ~Env{..} =+ bgroup "Stream" -- Fusion [ bgroup "stream" $- [ bench "Text" $ nf F.stream t- , bench "LazyText" $ nf FL.stream tl- ]- -- must perform exactly the same as stream above due to- -- stream/unstream (i.e. stream after unstream) fusion- , bgroup "stream-fusion" $- [ bench "Text" $ nf (F.stream . F.unstream . F.stream) t- , bench "LazyText" $ nf (FL.stream . FL.unstream . FL.stream) tl- ]- -- measure the overhead of unstream after stream- , bgroup "stream-unstream" $- [ bench "Text" $ nf (F.unstream . F.stream) t- , bench "LazyText" $ nf (FL.unstream . FL.stream) tl+ [ bench "Text" $ nf T.stream t+ , bench "LazyText" $ nf TL.stream tl ] -- Encoding.Fusion
benchmarks/haskell/Benchmarks/WordFrequencies.hs view
@@ -9,7 +9,8 @@ -- * Comparing: Eq/Ord instances -- module Benchmarks.WordFrequencies- ( benchmark+ ( initEnv+ , benchmark ) where import Criterion (Benchmark, bench, bgroup, whnf)@@ -21,12 +22,18 @@ import qualified Data.Text as T import qualified Data.Text.IO as T -benchmark :: FilePath -> IO Benchmark-benchmark fp = do+type Env = (String, B.ByteString, T.Text)++initEnv :: FilePath -> IO Env+initEnv fp = do s <- readFile fp b <- B.readFile fp t <- T.readFile fp- return $ bgroup "WordFrequencies"+ return (s, b, t)++benchmark :: Env -> Benchmark+benchmark ~(s, b, t) =+ bgroup "WordFrequencies" [ bench "String" $ whnf (frequencies . words . map toLower) s , bench "ByteString" $ whnf (frequencies . B.words . B.map toLower) b , bench "Text" $ whnf (frequencies . T.words . T.toLower) t
benchmarks/text-benchmarks.cabal view
@@ -1,3 +1,4 @@+cabal-version: 1.12 name: text-benchmarks version: 0.0.0.0 synopsis: Benchmarks for the text package@@ -12,7 +13,6 @@ maintainer: jaspervdj@gmail.com category: Text build-type: Simple-cabal-version: >=1.8 flag bytestring-builder description: Depend on the bytestring-builder package for backwards compatibility.@@ -42,6 +42,7 @@ ghc-prim, integer-gmp, stringsearch,+ template-haskell, transformers, utf8-string, vector@@ -129,6 +130,10 @@ Data.Text.Unsafe Data.Text.Show + default-language: Haskell2010+ default-extensions: NondecreasingIndentation++ executable text-multilang hs-source-dirs: haskell main-is: Multilang.hs@@ -138,3 +143,6 @@ bytestring, text, time++ default-language: Haskell2010+ default-extensions: NondecreasingIndentation
changelog.md view
@@ -1,8 +1,15 @@-#### 1.2.3.2+### 1.2.4.0 -* Special release supporting GHC 8.10.1 / `base-4.14.0.0` only+* Add TH `Lift` instances for `Data.Text.Text` and `Data.Text.Lazy.Text` (gh-232) -#### 1.2.3.1+* Update Haddock documentation to better reflect fusion eligibility; improve fusion+ rules for `takeWhileEnd` and `length` (gh-241, ghc-202)++* Optimise `Data.Text.replicate` from `O(n)` to `O(log n)` (gh-209)++* Support `base-4.13.0.0`++### 1.2.3.1 * Make `decodeUtf8With` fail explicitly for unsupported non-BMP replacement characters instead silent undefined behaviour (gh-213)
tests/text-tests.cabal view
@@ -146,7 +146,8 @@ binary, deepseq, ghc-prim,- integer-gmp+ integer-gmp,+ template-haskell if flag(bytestring-builder) build-depends: bytestring >= 0.9 && < 0.10.4,
text.cabal view
@@ -1,6 +1,6 @@-cabal-version: 1.12+cabal-version: >= 1.10 name: text-version: 1.2.3.2+version: 1.2.4.0 homepage: https://github.com/haskell/text bug-reports: https://github.com/haskell/text/issues@@ -29,13 +29,26 @@ . > import qualified Data.Text as T .+ == ICU Support+ . To use an extended and very rich family of functions for working with Unicode text (including normalization, regular expressions, non-standard encodings, text breaking, and locales), see the [text-icu package](https://hackage.haskell.org/package/text-icu) based on the well-respected and liberally licensed [ICU library](http://site.icu-project.org/).+ .+ == Internal Representation: UTF-16 vs. UTF-8+ .+ Currently the @text@ library uses UTF-16 as its internal representation+ which is [neither a fixed-width nor always the most dense representation](http://utf8everywhere.org/)+ for Unicode text. We're currently investigating the feasibility+ of [changing Text's internal representation to UTF-8](https://github.com/text-utf8)+ and if you need such a 'Text' type right now you might be interested in using the spin-off+ packages <https://hackage.haskell.org/package/text-utf8 text-utf8> and+ <https://hackage.haskell.org/package/text-short text-short>. + license: BSD2 license-file: LICENSE author: Bryan O'Sullivan <bos@serpentine.com>@@ -43,7 +56,9 @@ copyright: 2009-2011 Bryan O'Sullivan, 2008-2009 Tom Harper category: Data, Text build-type: Simple-tested-with: GHC==8.10.1+tested-with: GHC==8.6.5, GHC==8.4.4,+ GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4,+ GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4 extra-source-files: -- scripts/CaseFolding.txt -- scripts/SpecialCasing.txt@@ -69,6 +84,13 @@ tests/scripts/*.sh tests/text-tests.cabal +flag bytestring-builder+ description:+ Depend on the [bytestring-builder](https://hackage.haskell.org/package/bytestring-builder)+ package for backwards compatibility.+ default: False+ manual: False+ flag developer description: operate in developer mode default: False@@ -134,13 +156,19 @@ Data.Text.Show build-depends:- array == 0.5.*,- base == 4.14.*,- binary == 0.8.*,- deepseq >= 1.1.0.0 && < 1.5,- ghc-prim == 0.6.*,- bytestring >= 0.10.4 && < 0.11+ array >= 0.3 && < 0.6,+ base >= 4.3 && < 5,+ binary >= 0.5 && < 0.9,+ deepseq >= 1.1 && < 1.5,+ ghc-prim >= 0.2 && < 0.6,+ template-haskell >= 2.5 && < 2.16 + if flag(bytestring-builder)+ build-depends: bytestring >= 0.9 && < 0.10.4,+ bytestring-builder >= 0.10.4.0.2 && < 0.11+ else+ build-depends: bytestring >= 0.10.4 && < 0.11+ ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2 if flag(developer) ghc-prof-options: -auto-all@@ -175,6 +203,15 @@ UnboxedTuples UnliftedFFITypes + if impl(ghc >= 7.2)+ other-extensions: Trustworthy+ if impl(ghc >= 7.4)+ other-extensions: Safe+ if impl(ghc >= 8.0)+ other-extensions: TemplateHaskellQuotes+ else+ other-extensions: TemplateHaskell+ test-suite tests type: exitcode-stdio-1.0 c-sources: cbits/cbits.c@@ -262,10 +299,16 @@ ghc-prim, quickcheck-unicode >= 1.0.1.0, random,+ template-haskell, test-framework >= 0.4, test-framework-hunit >= 0.2,- test-framework-quickcheck2 >= 0.2,- bytestring >= 0.10.4+ test-framework-quickcheck2 >= 0.2++ if flag(bytestring-builder)+ build-depends: bytestring >= 0.9 && < 0.10.4,+ bytestring-builder >= 0.10.4+ else+ build-depends: bytestring >= 0.10.4 if flag(integer-simple) cpp-options: -DINTEGER_SIMPLE