on master help sign in
Implement and test lazy split and splitWith

--HG-- extra : convert_revision : eba7f1883aaeb3986519ed91dc6a76f8744b9ae2

commitd5b4606bebf82005c822a91c0a07eca1588ee248 authorBryan O'Sullivan <bos@serpentine.com> dateWed 4 Mar 2009, 06:10 (18 years ago) parentcb8194d
2 files changed+40−2
Data/Text/Lazy.hs+36−2 tests/Properties.hs+4
Data/Text/Lazy.hs+36−2
@@ -107,8 +107,8 @@ module Data.Text.Lazy
107107 , tails
108108
109109 -- ** Breaking into many substrings
110− -- , split
111− -- , splitWith
110+ , split
111+ , splitWith
112112 -- , breakSubstring
113113
114114 -- ** Breaking into lines and words
@@ -646,6 +646,40 @@ tails ts@(Chunk t ts')
646646 | T.length t == 1 = ts : tails ts'
647647 | otherwise = ts : tails (Chunk (T.unsafeTail t) ts')
648648
649+-- | /O(n)/ Break a 'Text' into pieces separated by the byte
650+-- argument, consuming the delimiter. I.e.
651+--
652+-- > split '\n' "a\nb\nd\ne" == ["a","b","d","e"]
653+-- > split 'a' "aXaXaXa" == ["","X","X","X",""]
654+-- > split 'x' "x" == ["",""]
655+--
656+-- and
657+--
658+-- > intercalate [c] . split c == id
659+-- > split == splitWith . (==)
660+--
661+-- As for all splitting functions in this library, this function does
662+-- not copy the substrings, it just constructs new 'Text's that are
663+-- slices of the original.
664+split :: Char -> Text -> [Text]
665+split c = splitWith (==c)
666+{-# INLINE split #-}
667+
668+-- | /O(n)/ Splits a 'Text' into components delimited by separators,
669+-- where the predicate returns True for a separator element. The
670+-- resulting components do not contain the separators. Two adjacent
671+-- separators result in an empty component in the output. eg.
672+--
673+-- > splitWith (=='a') "aabbaca" == ["","","bb","c",""]
674+-- > splitWith (=='a') [] == []
675+splitWith :: (Char -> Bool) -> Text -> [Text]
676+splitWith _ Empty = []
677+splitWith p (Chunk t0 ts0) = comb [] (T.splitWith p t0) ts0
678+ where comb acc (s:[]) Empty = revChunks (s:acc) : []
679+ comb acc (s:[]) (Chunk t ts) = comb (s:acc) (T.splitWith p t) ts
680+ comb acc (s:ss) ts = revChunks (s:acc) : comb [] ss ts
681+{-# INLINE splitWith #-}
682+
649683revChunks :: [T.Text] -> Text
650684revChunks = L.foldl' (flip chunk) Empty
651685
tests/Properties.hs+4
@@ -243,8 +243,10 @@ prop_T_tails = L.tails `eqP` (map unpackT . T.tails)
243243prop_TL_tails = L.tails `eqP` (map unpackT . TL.tails)
244244
245245prop_T_split_i c = id `eq` (T.intercalate (T.singleton c) . T.split c)
246+prop_TL_split_i c = id `eq` (TL.intercalate (TL.singleton c) . TL.split c)
246247
247248prop_T_splitWith p = splitWith p `eqP` (map unpackT . T.splitWith p)
249+prop_TL_splitWith p = splitWith p `eqP` (map unpackT . TL.splitWith p)
248250
249251splitWith _ "" = []
250252splitWith p s = if null s'
@@ -447,7 +449,9 @@ tests = [
447449 ("prop_TL_tails", mytest prop_TL_tails),
448450
449451 ("prop_T_split_i", mytest prop_T_split_i),
452+ ("prop_TL_split_i", mytest prop_TL_split_i),
450453 ("prop_T_splitWith", mytest prop_T_splitWith),
454+ ("prop_TL_splitWith", mytest prop_TL_splitWith),
451455 ("prop_T_breakSubstringC", mytest prop_T_breakSubstringC),
452456 ("prop_T_breakSubstring_isInfixOf", mytest prop_T_breakSubstring_isInfixOf),
453457