on master help sign in
Implement and test lazy map, intercalate, intersperse
ec34d1aBryan O'Sullivan
Data/Text/Lazy.hs+35−15
@@ -52,9 +52,9 @@ module Data.Text.Lazy
52 , length
52 , length
53
53
54 -- * Transformations
54 -- * Transformations
55− -- , map
55+ , map
56− -- , intercalate
56+ , intercalate
57− -- , intersperse
57+ , intersperse
58 -- , transpose
58 -- , transpose
59 -- , reverse
59 -- , reverse
60
60
@@ -153,6 +153,7 @@ import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
153 fromIntegral, not, return, otherwise)
153 fromIntegral, not, return, otherwise)
154import qualified Prelude as P
154import qualified Prelude as P
155import Data.Int (Int64)
155import Data.Int (Int64)
156+import qualified Data.List as L
156import Data.String (IsString(..))
157import Data.String (IsString(..))
157import qualified Data.Text as T
158import qualified Data.Text as T
158import qualified Data.Text.Fusion as S
159import qualified Data.Text.Fusion as S
@@ -296,18 +297,6 @@ null _ = False
296 S.null (stream t) = null t
297 S.null (stream t) = null t
297 #-}
298 #-}
298
299
299−length :: Text -> Int64
300−length = foldlChunks go 0
301− where go l t = l + fromIntegral (T.length t)
302−{-# INLINE [1] length #-}
303−
304−{-# RULES
305−"LAZY TEXT length -> fused" [~1] forall t.
306− length t = S.length64 (stream t)
307−"LAZY TEXT length -> unfused" [1] forall t.
308− S.length64 (stream t) = length t
309− #-}
310−
311-- | /O(1)/ Returns the last character of a 'Text', which must be
300-- | /O(1)/ Returns the last character of a 'Text', which must be
312-- non-empty. Subject to array fusion.
301-- non-empty. Subject to array fusion.
313last :: Text -> Char
302last :: Text -> Char
@@ -324,6 +313,37 @@ last (Chunk t ts) = go t ts
324 S.last (stream t) = last t
313 S.last (stream t) = last t
325 #-}
314 #-}
326
315
316+length :: Text -> Int64
317+length = foldlChunks go 0
318+ where go l t = l + fromIntegral (T.length t)
319+{-# INLINE [1] length #-}
320+
321+{-# RULES
322+"LAZY TEXT length -> fused" [~1] forall t.
323+ length t = S.length64 (stream t)
324+"LAZY TEXT length -> unfused" [1] forall t.
325+ S.length64 (stream t) = length t
326+ #-}
327+
328+-- | /O(n)/ 'map' @f @xs is the 'Text' obtained by applying @f@ to
329+-- each element of @xs@. Subject to array fusion.
330+map :: (Char -> Char) -> Text -> Text
331+map f t = unstream (S.map f (stream t))
332+{-# INLINE [1] map #-}
333+
334+-- | /O(n)/ The 'intercalate' function takes a 'Text' and a list of
335+-- 'Text's and concatenates the list after interspersing the first
336+-- argument between each element of the list.
337+intercalate :: Text -> [Text] -> Text
338+intercalate t ts = unstream (S.intercalate (stream t) (L.map stream ts))
339+{-# INLINE intercalate #-}
340+
341+-- | /O(n)/ The 'intersperse' function takes a character and places it
342+-- between the characters of a 'Text'. Subject to array fusion.
343+intersperse :: Char -> Text -> Text
344+intersperse c t = unstream (S.intersperse c (stream t))
345+{-# INLINE intersperse #-}
346+
327-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
347-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
328-- prefix of @t@ of length @n@, and whose second is the remainder of
348-- prefix of @t@ of length @n@, and whose second is the remainder of
329-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
349-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
tests/Properties.hs+6
@@ -141,8 +141,11 @@ prop_S_length64 = length `eqP` (fromIntegral . S.length64)
141prop_T_length = length `eqP` T.length
141prop_T_length = length `eqP` T.length
142prop_TL_length = length `eqP` (fromIntegral . TL.length)
142prop_TL_length = length `eqP` (fromIntegral . TL.length)
143prop_T_map f = map f `eqP` (unpackT . T.map f)
143prop_T_map f = map f `eqP` (unpackT . T.map f)
144+prop_TL_map f = map f `eqP` (unpackT . TL.map f)
144prop_T_intercalate c = L.intercalate c `eq` (unpackT . T.intercalate (T.pack c) . map T.pack)
145prop_T_intercalate c = L.intercalate c `eq` (unpackT . T.intercalate (T.pack c) . map T.pack)
146+prop_TL_intercalate c = L.intercalate c `eq` (unpackT . TL.intercalate (TL.pack c) . map TL.pack)
145prop_T_intersperse c = L.intersperse c `eqP` (unpackT . T.intersperse c)
147prop_T_intersperse c = L.intersperse c `eqP` (unpackT . T.intersperse c)
148+prop_TL_intersperse c = L.intersperse c `eqP` (unpackT . TL.intersperse c)
146prop_T_transpose = L.transpose `eq` (map unpackT . T.transpose . map T.pack)
149prop_T_transpose = L.transpose `eq` (map unpackT . T.transpose . map T.pack)
147prop_T_reverse = L.reverse `eqP` (unpackT . T.reverse)
150prop_T_reverse = L.reverse `eqP` (unpackT . T.reverse)
148prop_T_reverse_short n = L.reverse `eqP` (unpackT . S.reverse . shorten n . S.stream)
151prop_T_reverse_short n = L.reverse `eqP` (unpackT . S.reverse . shorten n . S.stream)
@@ -326,8 +329,11 @@ tests = [
326 ("prop_TL_length", mytest prop_TL_length),
329 ("prop_TL_length", mytest prop_TL_length),
327
330
328 ("prop_T_map", mytest prop_T_map),
331 ("prop_T_map", mytest prop_T_map),
332+ ("prop_TL_map", mytest prop_TL_map),
329 ("prop_T_intercalate", mytest prop_T_intercalate),
333 ("prop_T_intercalate", mytest prop_T_intercalate),
334+ ("prop_TL_intercalate", mytest prop_TL_intercalate),
330 ("prop_T_intersperse", mytest prop_T_intersperse),
335 ("prop_T_intersperse", mytest prop_T_intersperse),
336+ ("prop_TL_intersperse", mytest prop_TL_intersperse),
331 ("prop_T_transpose", mytest prop_T_transpose),
337 ("prop_T_transpose", mytest prop_T_transpose),
332 ("prop_T_reverse", mytest prop_T_reverse),
338 ("prop_T_reverse", mytest prop_T_reverse),
333 ("prop_T_reverse_short", mytest prop_T_reverse_short),
339 ("prop_T_reverse_short", mytest prop_T_reverse_short),