on master help sign in
Get rid of the fused version of concat.
e63b869Bryan O'Sullivan
Data/Text.hs+25−12
@@ -1,4 +1,4 @@
1−{-# LANGUAGE BangPatterns #-}
1+{-# LANGUAGE BangPatterns, Rank2Types #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
3
3
4-- |
4-- |
@@ -164,10 +164,12 @@ module Data.Text
164import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
164import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
165 Eq(..), Ord(..), (++),
165 Eq(..), Ord(..), (++),
166 Read(..), Show(..),
166 Read(..), Show(..),
167− (&&), (||), (+), (-), (.), ($),
167+ (&&), (||), (+), (-), (.), ($), (>>),
168 fromIntegral, div, not, return, otherwise)
168 fromIntegral, div, not, return, otherwise)
169+import Control.DeepSeq (NFData)
169import Control.Exception (assert)
170import Control.Exception (assert)
170import Data.Char (isSpace)
171import Data.Char (isSpace)
172+import Control.Monad (foldM)
171import Control.Monad.ST (ST)
173import Control.Monad.ST (ST)
172import qualified Data.Text.Array as A
174import qualified Data.Text.Array as A
173import qualified Data.List as L
175import qualified Data.List as L
@@ -212,6 +214,8 @@ instance Monoid Text where
212instance IsString Text where
214instance IsString Text where
213 fromString = pack
215 fromString = pack
214
216
217+instance NFData Text
218+
215-- -----------------------------------------------------------------------------
219-- -----------------------------------------------------------------------------
216-- * Conversion to/from 'Text'
220-- * Conversion to/from 'Text'
217
221
@@ -254,15 +258,10 @@ append (Text arr1 off1 len1) (Text arr2 off2 len2) = Text (A.run x) 0 len
254 where
258 where
255 len = len1+len2
259 len = len1+len2
256 x = do
260 x = do
257− arr <- A.unsafeNew len :: ST s (A.MArray s Word16)
261+ arr <- A.unsafeNew len
258− copy arr1 off1 (len1+off1) arr 0
262+ copy arr 0 arr1 off1 len1
259− copy arr2 off2 (len2+off2) arr len1
263+ copy arr len1 arr2 off2 (len1+len2)
260 return arr
264 return arr
261− where
262− copy arr i top arr' j
263− | i >= top = return ()
264− | otherwise = do A.unsafeWrite arr' j (arr `A.unsafeIndex` i)
265− copy arr (i+1) top arr' (j+1)
266{-# INLINE append #-}
265{-# INLINE append #-}
267
266
268{-# RULES
267{-# RULES
@@ -272,6 +271,14 @@ append (Text arr1 off1 len1) (Text arr2 off2 len2) = Text (A.run x) 0 len
272 unstream (S.append (stream t1) (stream t2)) = append t1 t2
271 unstream (S.append (stream t1) (stream t2)) = append t1 t2
273 #-}
272 #-}
274
273
274+copy :: forall s. A.MArray s Word16 -> Int -> A.Array Word16 -> Int -> Int
275+ -> ST s ()
276+copy dest i0 src j0 top = go i0 j0
277+ where
278+ go i j | i >= top = return ()
279+ | otherwise = do A.unsafeWrite dest i (src `A.unsafeIndex` j)
280+ go (i+1) (j+1)
281+
275-- | /O(1)/ Returns the first character of a 'Text', which must be
282-- | /O(1)/ Returns the first character of a 'Text', which must be
276-- non-empty. Subject to fusion.
283-- non-empty. Subject to fusion.
277head :: Text -> Char
284head :: Text -> Char
@@ -555,9 +562,15 @@ foldr1 f t = S.foldr1 f (stream t)
555-- -----------------------------------------------------------------------------
562-- -----------------------------------------------------------------------------
556-- ** Special folds
563-- ** Special folds
557
564
558−-- | /O(n)/ Concatenate a list of 'Text's. Subject to fusion.
565+-- | /O(n)/ Concatenate a list of 'Text's.
559concat :: [Text] -> Text
566concat :: [Text] -> Text
560−concat ts = unstream (S.concat (L.map stream ts))
567+concat ts = Text (A.run go) 0 len
568+ where
569+ len = L.sum (L.map (\(Text _ _ l) -> l) ts)
570+ go = do
571+ arr <- A.unsafeNew len
572+ let step i (Text a o l) = let j = i + l in copy arr i a o j >> return j
573+ foldM step 0 ts >> return arr
561{-# INLINE concat #-}
574{-# INLINE concat #-}
562
575
563-- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and
576-- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and