on master help sign in
Implement and test lazy break and span

--HG-- extra : convert_revision : 8df3cf5ee866021234b00e85ff7dd03571bffbd0

commit20d7203a3de0a3752a182874c06bc6b9f678e704 authorBryan O'Sullivan <bos@serpentine.com> dateWed 4 Mar 2009, 05:41 (18 years ago) parent919bf33
2 files changed+32−4
Data/Text/Lazy.hs+28−4 tests/Properties.hs+4
Data/Text/Lazy.hs+28−4
@@ -99,8 +99,8 @@ module Data.Text.Lazy
9999 , takeWhile
100100 , dropWhile
101101 , splitAt
102− -- , span
103− -- , break
102+ , span
103+ , break
104104 -- , group
105105 -- , groupBy
106106 -- , inits
@@ -150,7 +150,7 @@ import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
150150 Eq(..), Ord(..), (++),
151151 Read(..), Show(..),
152152 (&&), (||), (+), (-), (.), ($),
153− fromIntegral, not, return, otherwise)
153+ flip, fromIntegral, not, return, otherwise)
154154import qualified Prelude as P
155155import Data.Int (Int64)
156156import qualified Data.List as L
@@ -586,7 +586,31 @@ splitAt = loop
586586 in (Chunk ts' Empty, Chunk ts'' Empty)
587587 | otherwise = let (ts',ts'') = loop (n - len) ts
588588 in (Chunk t ts', ts'')
589− where len = T.length t
589+ where len = fromIntegral (T.length t)
590+
591+-- | /O(n)/ 'break' is like 'span', but the prefix returned is over
592+-- elements that fail the predicate @p@.
593+break :: (Char -> Bool) -> Text -> (Text, Text)
594+break p t0 = break' t0
595+ where break' Empty = (empty, empty)
596+ break' c@(Chunk t ts) =
597+ case T.findIndex p t of
598+ Nothing -> let (ts', ts'') = break' ts
599+ in (Chunk t ts', ts'')
600+ Just n | n == 0 -> (Empty, c)
601+ | otherwise -> let (a,b) = T.splitAt n t
602+ in (Chunk a Empty, Chunk b ts)
603+
604+-- | /O(n)/ 'span', applied to a predicate @p@ and text @t@, returns a
605+-- pair whose first element is the longest prefix (possibly empty) of
606+-- @t@ of elements that satisfy @p@, and whose second is the remainder
607+-- of the list.
608+span :: (Char -> Bool) -> Text -> (Text, Text)
609+span p = break (not . p)
610+{-# INLINE span #-}
611+
612+revChunks :: [T.Text] -> Text
613+revChunks = L.foldl' (flip chunk) Empty
590614
591615emptyError :: String -> a
592616emptyError fun = P.error ("Data.Text.Lazy." ++ fun ++ ": empty input")
tests/Properties.hs+4
@@ -230,7 +230,9 @@ prop_TL_dropWhile p = L.dropWhile p `eqP` (unpackT . S.dropWhile p)
230230prop_T_splitAt n = L.splitAt n `eqP` (unpack2 . T.splitAt n)
231231prop_TL_splitAt n = L.splitAt n `eqP` (unpack2 . TL.splitAt (fromIntegral n))
232232prop_T_span p = L.span p `eqP` (unpack2 . T.span p)
233+prop_TL_span p = L.span p `eqP` (unpack2 . TL.span p)
233234prop_T_break p = L.break p `eqP` (unpack2 . T.break p)
235+prop_TL_break p = L.break p `eqP` (unpack2 . TL.break p)
234236prop_T_group = L.group `eqP` (map unpackT . T.group)
235237prop_T_groupBy p = L.groupBy p `eqP` (map unpackT . T.groupBy p)
236238prop_T_inits = L.inits `eqP` (map unpackT . T.inits)
@@ -428,7 +430,9 @@ tests = [
428430 ("prop_TL_dropWhile", mytest prop_TL_dropWhile),
429431 ("prop_T_splitAt", mytest prop_T_splitAt),
430432 ("prop_T_span", mytest prop_T_span),
433+ ("prop_TL_span", mytest prop_TL_span),
431434 ("prop_T_break", mytest prop_T_break),
435+ ("prop_TL_break", mytest prop_TL_break),
432436 ("prop_T_group", mytest prop_T_group),
433437 ("prop_T_groupBy", mytest prop_T_groupBy),
434438 ("prop_T_inits", mytest prop_T_inits),