text 0.6 → 0.7
raw patch · 5 files changed
+617/−2 lines, 5 files
Files
- Data/Text/IO.hs +252/−0
- Data/Text/IO/Internal.hs +164/−0
- Data/Text/Lazy/IO.hs +173/−0
- Data/Text/Unsafe.hs +24/−1
- text.cabal +4/−1
+ Data/Text/IO.hs view
@@ -0,0 +1,252 @@+{-# LANGUAGE BangPatterns, CPP, RecordWildCards #-}+-- |+-- Module : Data.Text.IO+-- Copyright : (c) Bryan O'Sullivan 2009,+-- (c) Simon Marlow 2009+-- License : BSD-style+-- Maintainer : bos@serpentine.com+-- Stability : experimental+-- Portability : GHC+--+-- Efficient locale-sensitive support for text I\/O.++module Data.Text.IO+ (+ -- * Locale support+ -- $locale+ -- * File-at-a-time operations+ readFile+ , writeFile+ , appendFile+ -- * Operations on handles+ , hGetContents+ , hGetLine+ , hPutStr+ , hPutStrLn+ -- * Special cases for standard input and output+ , interact+ , getContents+ , getLine+ , putStr+ , putStrLn+ ) where++import Data.Text (Text)+import Prelude hiding (appendFile, getContents, getLine, interact, putStr,+ putStrLn, readFile, writeFile)+import System.IO (Handle, IOMode(..), hPutChar, openFile, stdin, stdout,+ withFile)+#if __GLASGOW_HASKELL__ <= 610+import qualified Data.ByteString.Char8 as B+import Data.Text.Encoding (decodeUtf8, encodeUtf8)+#else+import Control.Exception (throw)+import Data.IORef (readIORef, writeIORef)+import qualified Data.Text as T+import Data.Text.Fusion (stream)+import Data.Text.Fusion.Internal (Step(..), Stream(..))+import Data.Text.IO.Internal (hGetLineWith, readChunk)+import GHC.IO.Buffer (Buffer(..), BufferState(..), CharBufElem, CharBuffer,+ RawCharBuffer, emptyBuffer, isEmptyBuffer, newCharBuffer,+ writeCharBuf)+import GHC.IO.Handle.Internals (augmentIOError, hClose_help, wantReadableHandle,+ wantWritableHandle)+import GHC.IO.Handle.Text (commitBuffer')+import GHC.IO.Handle.Types (BufferList(..), BufferMode(..), Handle__(..),+ Newline(..))+import System.IO.Error (isEOFError)+#endif++-- | The 'readFile' function reads a file and returns the contents of+-- the file as a string. The entire file is read strictly, as with+-- 'getContents'.+readFile :: FilePath -> IO Text+readFile name = openFile name ReadMode >>= hGetContents++-- | Write a string to a file. The file is truncated to zero length+-- before writing begins.+writeFile :: FilePath -> Text -> IO ()+writeFile p = withFile p WriteMode . flip hPutStr++-- | Write a string the end of a file.+appendFile :: FilePath -> Text -> IO ()+appendFile p = withFile p AppendMode . flip hPutStr++-- | Read the remaining contents of a 'Handle' as a string. The+-- 'Handle' is closed once the contents have been read, or if an+-- exception is thrown.+--+-- Internally, this function reads a chunk at a time from the+-- lower-level buffering abstraction, and concatenates the chunks into+-- a single string once the entire file has been read.+--+-- As a result, it requires approximately twice as much memory as its+-- result to construct its result. For files more than a half of+-- available RAM in size, this may result in memory exhaustion.+hGetContents :: Handle -> IO Text+#if __GLASGOW_HASKELL__ <= 610+hGetContents = fmap decodeUtf8 . B.hGetContents+#else+hGetContents h = wantReadableHandle "hGetContents" h $ \hh -> do+ (hh',ts) <- readAll hh+ return (hh',T.concat ts)+ where+ readAll hh@Handle__{..} = do+ buf <- readIORef haCharBuffer+ let readChunks = do+ t <- readChunk hh buf+ (hh',ts) <- readAll hh+ return (hh', t:ts)+ readChunks `catch` \e -> do+ (hh', _) <- hClose_help hh+ if isEOFError e+ then return $ if isEmptyBuffer buf+ then (hh', [])+ else (hh', [T.singleton '\r'])+ else throw (augmentIOError e "hGetContents" h)+#endif+ +-- | Read a single line from a handle.+hGetLine :: Handle -> IO Text+#if __GLASGOW_HASKELL__ <= 610+hGetLine = fmap decodeUtf8 . B.hGetLine+#else+hGetLine = hGetLineWith T.concat+#endif++-- | Write a string to a handle.+hPutStr :: Handle -> Text -> IO ()+#if __GLASGOW_HASKELL__ <= 610+hPutStr h = B.hPutStr h . encodeUtf8+#else+-- This function is lifted almost verbatim from GHC.IO.Handle.Text.+hPutStr h t = do+ (buffer_mode, nl) <- + wantWritableHandle "hPutStr" h $ \h_ -> do+ bmode <- getSpareBuffer h_+ return (bmode, haOutputNL h_)+ let str = stream t+ case buffer_mode of+ (NoBuffering, _) -> hPutChars h str+ (LineBuffering, buf) -> writeBlocks h True nl buf str+ (BlockBuffering _, buf) -> writeBlocks h False nl buf str++hPutChars :: Handle -> Stream Char -> IO ()+hPutChars h (Stream next0 s0 _len) = loop s0+ where+ loop !s = case next0 s of+ Done -> return ()+ Skip s' -> loop s'+ Yield x s' -> hPutChar h x >> loop s'++-- This function is largely lifted from GHC.IO.Handle.Text, but+-- adapted to a coinductive stream of data instead of an inductive+-- list.+writeBlocks :: Handle -> Bool -> Newline -> Buffer CharBufElem -> Stream Char+ -> IO ()+writeBlocks h lineBuffered nl buf0 (Stream next0 s0 _len) = outer s0 buf0+ where+ outer s1 Buffer{bufRaw=raw, bufSize=len} = inner s1 (0::Int)+ where+ inner !s !n =+ case next0 s of+ Done -> commit n False{-no flush-} True{-release-} >> return ()+ Skip s' -> inner s' n+ Yield x s'+ | n + 1 >= len -> commit n True{-needs flush-} False >>= outer s+ | x == '\n' -> do+ n' <- if nl == CRLF+ then do n1 <- writeCharBuf raw n '\r'+ writeCharBuf raw n1 '\n'+ else writeCharBuf raw n x+ if lineBuffered+ then commit n' True{-needs flush-} False >>= outer s'+ else inner s' n'+ | otherwise -> writeCharBuf raw n x >>= inner s'+ commit = commitBuffer h raw len++-- This function is completely lifted from GHC.IO.Handle.Text.+getSpareBuffer :: Handle__ -> IO (BufferMode, CharBuffer)+getSpareBuffer Handle__{haCharBuffer=ref, + haBuffers=spare_ref,+ haBufferMode=mode}+ = do+ case mode of+ NoBuffering -> return (mode, error "no buffer!")+ _ -> do+ bufs <- readIORef spare_ref+ buf <- readIORef ref+ case bufs of+ BufferListCons b rest -> do+ writeIORef spare_ref rest+ return ( mode, emptyBuffer b (bufSize buf) WriteBuffer)+ BufferListNil -> do+ new_buf <- newCharBuffer (bufSize buf) WriteBuffer+ return (mode, new_buf)+++-- This function is completely lifted from GHC.IO.Handle.Text.+commitBuffer :: Handle -> RawCharBuffer -> Int -> Int -> Bool -> Bool+ -> IO CharBuffer+commitBuffer hdl !raw !sz !count flush release = + wantWritableHandle "commitAndReleaseBuffer" hdl $+ commitBuffer' raw sz count flush release+{-# NOINLINE commitBuffer #-}+#endif++-- | Write a string to a handle, followed by a newline.+hPutStrLn :: Handle -> Text -> IO ()+hPutStrLn h t = hPutStr h t >> hPutChar h '\n'++-- | The 'interact' function takes a function of type @Text -> Text@+-- as its argument. The entire input from the standard input device is+-- passed to this function as its argument, and the resulting string+-- is output on the standard output device.+interact :: (Text -> Text) -> IO ()+interact f = putStr . f =<< getContents++-- | Read all user input on 'stdin' as a single string.+getContents :: IO Text+getContents = hGetContents stdin++-- | Read a single line of user input from 'stdin'.+getLine :: IO Text+getLine = hGetLine stdin++-- | Write a string to 'stdout'.+putStr :: Text -> IO ()+putStr = hPutStr stdout++-- | Write a string to 'stdout', followed by a newline.+putStrLn :: Text -> IO ()+putStrLn = hPutStrLn stdout++-- $locale+--+-- /Note/: The behaviour of functions in this module depends on the+-- version of GHC you are using.+--+-- Beginning with GHC 6.12, text I\/O is performed using the system or+-- handle's current locale and line ending conventions.+--+-- Under GHC 6.10 and earlier, the system I\/O libraries /do not+-- support/ locale-sensitive I\/O or line ending conversion. On these+-- versions of GHC, functions in this library all use UTF-8. What+-- does this mean in practice?+--+-- * All data that is read will be decoded as UTF-8.+--+-- * Before data is written, it is first encoded as UTF-8.+--+-- * On both reading and writing, the platform's native newline+-- conversion is performed.+--+-- If you must use a non-UTF-8 locale on an older version of GHC, you+-- will have to perform the transcoding yourself, e.g. as follows:+--+-- > import qualified Data.ByteString as B+-- > import Data.Text (Text)+-- > import Data.Text.Encoding (encodeUtf16)+-- >+-- > putStr_Utf16LE :: Text -> IO ()+-- > putStr_Utf16LE t = B.putStr (encodeUtf16LE t)
+ Data/Text/IO/Internal.hs view
@@ -0,0 +1,164 @@+{-# LANGUAGE BangPatterns, CPP, RecordWildCards #-}+-- |+-- Module : Data.Text.IO.Internal+-- Copyright : (c) Bryan O'Sullivan 2009,+-- (c) Simon Marlow 2009+-- License : BSD-style+-- Maintainer : bos@serpentine.com+-- Stability : experimental+-- Portability : GHC+--+-- Low-level support for text I\/O.++module Data.Text.IO.Internal+ (+#if __GLASGOW_HASKELL__ >= 612+ hGetLineWith+ , readChunk+#endif+ ) where++#if __GLASGOW_HASKELL__ >= 612+import Data.IORef (readIORef, writeIORef)+import Data.Text (Text)+import Data.Text.Fusion (unstream)+import Data.Text.Fusion.Internal (Step(..), Stream(..))+import Data.Text.Fusion.Size (exactSize, maxSize)+import Data.Text.Unsafe (inlinePerformIO)+import Foreign.Storable (peekElemOff)+import GHC.IO.Buffer (Buffer(..), CharBuffer, RawCharBuffer, bufferAdjustL,+ bufferElems, charSize, isEmptyBuffer, readCharBuf,+ withRawBuffer, writeCharBuf)+import GHC.IO.Handle.Internals (ioe_EOF, readTextDevice, wantReadableHandle_)+import GHC.IO.Handle.Types (Handle__(..), Newline(..))+import System.IO (Handle)+import System.IO.Error (isEOFError)+import qualified Data.Text as T++-- | Read a single line of input from a handle, constructing a list of+-- decoded chunks as we go. When we're done, transform them into the+-- destination type.+hGetLineWith :: ([Text] -> t) -> Handle -> IO t+hGetLineWith f h = wantReadableHandle_ "hGetLine" h go+ where+ go hh@Handle__{..} = readIORef haCharBuffer >>= fmap f . hGetLineLoop hh []++hGetLineLoop :: Handle__ -> [Text] -> CharBuffer -> IO [Text]+hGetLineLoop hh@Handle__{..} ts buf@Buffer{ bufL=r0, bufR=w, bufRaw=raw0 } = do+ let findEOL raw r | r == w = return (False, w)+ | otherwise = do+ (c,r') <- readCharBuf raw r+ if c == '\n'+ then return (True, r)+ else findEOL raw r'+ (eol, off) <- findEOL raw0 r0+ (t,r') <- if haInputNL == CRLF+ then unpack_nl raw0 r0 off+ else do t <- unpack raw0 r0 off+ return (t,off)+ if eol+ then do writeIORef haCharBuffer (bufferAdjustL (off+1) buf)+ return $ reverse (t:ts)+ else do+ let buf1 = bufferAdjustL r' buf+ maybe_buf <- maybeFillReadBuffer hh buf1+ case maybe_buf of+ -- Nothing indicates we caught an EOF, and we may have a+ -- partial line to return.+ Nothing -> do+ -- we reached EOF. There might be a lone \r left+ -- in the buffer, so check for that and+ -- append it to the line if necessary.+ let pre | isEmptyBuffer buf1 = T.empty+ | otherwise = T.singleton '\r'+ writeIORef haCharBuffer buf1{ bufL=0, bufR=0 }+ let str = reverse $ pre:t:ts+ if all T.null str+ then ioe_EOF+ else return str+ Just new_buf -> hGetLineLoop hh (t:ts) new_buf++-- This function is lifted almost verbatim from GHC.IO.Handle.Text.+maybeFillReadBuffer :: Handle__ -> CharBuffer -> IO (Maybe CharBuffer)+maybeFillReadBuffer handle_ buf+ = catch (Just `fmap` getSomeCharacters handle_ buf) $ \e ->+ if isEOFError e + then return Nothing + else ioError e++unpack :: RawCharBuffer -> Int -> Int -> IO Text+unpack !buf !r !w+ | charSize /= 4 = sizeError "unpack"+ | r >= w = return T.empty+ | otherwise = withRawBuffer buf go+ where+ go pbuf = return $! unstream (Stream next r (exactSize (w-r)))+ where+ next !i | i >= w = Done+ | otherwise = Yield (ix i) (i+1)+ ix i = inlinePerformIO $ peekElemOff pbuf i++unpack_nl :: RawCharBuffer -> Int -> Int -> IO (Text, Int)+unpack_nl !buf !r !w+ | charSize /= 4 = sizeError "unpack_nl"+ | r >= w = return (T.empty, 0)+ | otherwise = withRawBuffer buf $ go+ where+ go pbuf = do+ let t = unstream (Stream next r (maxSize (w-r)))+ w' = w - 1+ return $ if ix w' == '\r'+ then (t,w')+ else (t,w)+ where+ next !i | i >= w = Done+ | c == '\r' = let i' = i + 1+ in if i' < w+ then if ix i' == '\n'+ then Yield '\n' (i+2)+ else Yield '\n' i'+ else Done+ | otherwise = Yield c (i+1)+ where c = ix i+ ix i = inlinePerformIO $ peekElemOff pbuf i++-- This function is completely lifted from GHC.IO.Handle.Text.+getSomeCharacters :: Handle__ -> CharBuffer -> IO CharBuffer+getSomeCharacters handle_@Handle__{..} buf@Buffer{..} =+ case bufferElems buf of+ -- buffer empty: read some more+ 0 -> readTextDevice handle_ buf++ -- if the buffer has a single '\r' in it and we're doing newline+ -- translation: read some more+ 1 | haInputNL == CRLF -> do+ (c,_) <- readCharBuf bufRaw bufL+ if c == '\r'+ then do -- shuffle the '\r' to the beginning. This is only safe+ -- if we're about to call readTextDevice, otherwise it+ -- would mess up flushCharBuffer.+ -- See [note Buffer Flushing], GHC.IO.Handle.Types+ _ <- writeCharBuf bufRaw 0 '\r'+ let buf' = buf{ bufL=0, bufR=1 }+ readTextDevice handle_ buf'+ else do+ return buf++ -- buffer has some chars in it already: just return it+ _otherwise -> return buf++-- | Read a single chunk of strict text from a buffer. Used by both+-- the strict and lazy implementations of hGetContents.+readChunk :: Handle__ -> CharBuffer -> IO Text+readChunk hh@Handle__{..} buf = do+ buf'@Buffer{..} <- getSomeCharacters hh buf+ (t,r) <- if haInputNL == CRLF+ then unpack_nl bufRaw bufL bufR+ else do t <- unpack bufRaw bufL bufR+ return (t,bufR)+ writeIORef haCharBuffer (bufferAdjustL r buf')+ return t++sizeError :: String -> a+sizeError loc = error $ "Data.Text.IO." ++ loc ++ ": bad internal buffer size"+#endif
+ Data/Text/Lazy/IO.hs view
@@ -0,0 +1,173 @@+{-# LANGUAGE BangPatterns, CPP, RecordWildCards #-}+-- |+-- Module : Data.Text.Lazy.IO+-- Copyright : (c) Bryan O'Sullivan 2009,+-- (c) Simon Marlow 2009+-- License : BSD-style+-- Maintainer : bos@serpentine.com+-- Stability : experimental+-- Portability : GHC+--+-- Efficient locale-sensitive support for text I\/O.++module Data.Text.Lazy.IO+ (+ -- * Locale support+ -- $locale+ -- * File-at-a-time operations+ readFile+ , writeFile+ , appendFile+ -- * Operations on handles+ , hGetContents+ , hGetLine+ , hPutStr+ , hPutStrLn+ -- * Special cases for standard input and output+ , interact+ , getContents+ , getLine+ , putStr+ , putStrLn+ ) where++import Data.Text.Lazy.Internal (Text(..))+import Prelude hiding (appendFile, getContents, getLine, interact, putStr,+ putStrLn, readFile, writeFile)+import System.IO (Handle, IOMode(..), hPutChar, openFile, stdin, stdout,+ withFile)+import qualified Data.Text.IO as T+import qualified Data.Text.Lazy as L+#if __GLASGOW_HASKELL__ <= 610+import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)+import qualified Data.ByteString.Char8 as S8+import qualified Data.ByteString.Lazy.Char8 as L8+#else+import Control.Exception (throw)+import Data.IORef (readIORef)+import Data.Text.IO.Internal (hGetLineWith, readChunk)+import GHC.IO.Buffer (isEmptyBuffer)+import GHC.IO.Exception (IOException(..), IOErrorType(..), ioException)+import GHC.IO.Handle.Internals (augmentIOError, hClose_help,+ wantReadableHandle, withHandle)+import GHC.IO.Handle.Types (Handle__(..), HandleType(..))+import System.IO.Error (isEOFError)+import System.IO.Unsafe (unsafeInterleaveIO)+#endif++-- | The 'readFile' function reads a file and returns the contents of+-- the file as a string. The entire file is read strictly, as with+-- 'getContents'.+readFile :: FilePath -> IO Text+readFile name = openFile name ReadMode >>= hGetContents++-- | Write a string to a file. The file is truncated to zero length+-- before writing begins.+writeFile :: FilePath -> Text -> IO ()+writeFile p = withFile p WriteMode . flip hPutStr++-- | Write a string the end of a file.+appendFile :: FilePath -> Text -> IO ()+appendFile p = withFile p AppendMode . flip hPutStr++hGetContents :: Handle -> IO Text+#if __GLASGOW_HASKELL__ <= 610+hGetContents = fmap decodeUtf8 . L8.hGetContents+#else+hGetContents h =+ wantReadableHandle "hGetContents" h $ \hh -> do+ ts <- lazyRead h+ return (hh{haType=SemiClosedHandle}, ts)++lazyRead :: Handle -> IO Text+lazyRead h = unsafeInterleaveIO $+ withHandle "hGetContents" h $ \hh -> do+ case haType hh of+ ClosedHandle -> return (hh, L.empty)+ SemiClosedHandle -> lazyReadBuffered h hh+ _ -> ioException + (IOError (Just h) IllegalOperation "hGetContents"+ "illegal handle type" Nothing Nothing)++lazyReadBuffered :: Handle -> Handle__ -> IO (Handle__, Text)+lazyReadBuffered h hh@Handle__{..} = do+ buf <- readIORef haCharBuffer+ (do t <- readChunk hh buf+ ts <- lazyRead h+ return (hh, Chunk t ts)) `catch` \e -> do+ (hh', _) <- hClose_help hh+ if isEOFError e+ then return $ if isEmptyBuffer buf+ then (hh', Empty)+ else (hh', L.singleton '\r')+ else throw (augmentIOError e "hGetContents" h)+#endif++-- | Read a single line from a handle.+hGetLine :: Handle -> IO Text+#if __GLASGOW_HASKELL__ <= 610+hGetLine = fmap (decodeUtf8 . L8.fromChunks . (:[])) . S8.hGetLine+#else+hGetLine = hGetLineWith L.fromChunks+#endif++-- | Write a string to a handle.+hPutStr :: Handle -> Text -> IO ()+hPutStr h = mapM_ (T.hPutStr h) . L.toChunks++-- | Write a string to a handle, followed by a newline.+hPutStrLn :: Handle -> Text -> IO ()+hPutStrLn h t = hPutStr h t >> hPutChar h '\n'++-- | The 'interact' function takes a function of type @Text -> Text@+-- as its argument. The entire input from the standard input device is+-- passed to this function as its argument, and the resulting string+-- is output on the standard output device.+interact :: (Text -> Text) -> IO ()+interact f = putStr . f =<< getContents++-- | Read all user input on 'stdin' as a single string.+getContents :: IO Text+getContents = hGetContents stdin++-- | Read a single line of user input from 'stdin'.+getLine :: IO Text+getLine = hGetLine stdin++-- | Write a string to 'stdout'.+putStr :: Text -> IO ()+putStr = hPutStr stdout++-- | Write a string to 'stdout', followed by a newline.+putStrLn :: Text -> IO ()+putStrLn = hPutStrLn stdout++-- $locale+--+-- /Note/: The behaviour of functions in this module depends on the+-- version of GHC you are using.+--+-- Beginning with GHC 6.12, text I\/O is performed using the system or+-- handle's current locale and line ending conventions.+--+-- Under GHC 6.10 and earlier, the system I\/O libraries /do not+-- support/ locale-sensitive I\/O or line ending conversion. On these+-- versions of GHC, functions in this library all use UTF-8. What+-- does this mean in practice?+--+-- * All data that is read will be decoded as UTF-8.+--+-- * Before data is written, it is first encoded as UTF-8.+--+-- * On both reading and writing, the platform's native newline+-- conversion is performed.+--+-- If you must use a non-UTF-8 locale on an older version of GHC, you+-- will have to perform the transcoding yourself, e.g. as follows:+--+-- > import qualified Data.ByteString.Lazy as B+-- > import Data.Text.Lazy (Text)+-- > import Data.Text.Lazy.Encoding (encodeUtf16)+-- >+-- > putStr_Utf16LE :: Text -> IO ()+-- > putStr_Utf16LE t = B.putStr (encodeUtf16LE t)
Data/Text/Unsafe.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP, MagicHash, UnboxedTuples #-} -- | -- Module : Data.Text.Unsafe -- Copyright : (c) Bryan O'Sullivan 2009@@ -11,7 +12,8 @@ -- use in heavily tested code. module Data.Text.Unsafe (- iter+ inlinePerformIO+ , iter , iter_ , reverseIter , unsafeHead@@ -23,6 +25,14 @@ import Data.Text.UnsafeChar (unsafeChr) import Data.Text.Encoding.Utf16 (chr2) import qualified Data.Text.Array as A+#if defined(__GLASGOW_HASKELL__)+# if __GLASGOW_HASKELL__ >= 611+import GHC.IO (IO(IO))+# else+import GHC.IOBase (IO(IO))+# endif+import GHC.Base (realWorld#)+#endif -- | /O(1)/ A variant of 'head' for non-empty 'Text'. 'unsafeHead' -- omits the check for the empty case, so there is an obligation on@@ -77,3 +87,16 @@ j = assert (i >= 0) $ off + i k = j - 1 {-# INLINE reverseIter #-}++-- | Just like unsafePerformIO, but we inline it. Big performance gains as+-- it exposes lots of things to further inlining. /Very unsafe/. In+-- particular, you should do no memory allocation inside an+-- 'inlinePerformIO' block. On Hugs this is just @unsafePerformIO@.+--+{-# INLINE inlinePerformIO #-}+inlinePerformIO :: IO a -> a+#if defined(__GLASGOW_HASKELL__)+inlinePerformIO (IO m) = case m realWorld# of (# _, r #) -> r+#else+inlinePerformIO = unsafePerformIO+#endif
text.cabal view
@@ -1,5 +1,5 @@ name: text-version: 0.6+version: 0.7 synopsis: An efficient packed Unicode text type description: An efficient packed Unicode text type. license: BSD3@@ -38,8 +38,10 @@ Data.Text.Encoding Data.Text.Encoding.Error Data.Text.Foreign+ Data.Text.IO Data.Text.Lazy Data.Text.Lazy.Encoding+ Data.Text.Lazy.IO other-modules: Data.Text.Array Data.Text.Encoding.Fusion@@ -52,6 +54,7 @@ Data.Text.Fusion.Common Data.Text.Fusion.Internal Data.Text.Fusion.Size+ Data.Text.IO.Internal Data.Text.Internal Data.Text.Lazy.Encoding.Fusion Data.Text.Lazy.Fusion