on master help sign in
Implement and test lazy takeWhile and dropWhile

--HG-- extra : convert_revision : ad555de4c9c9a3400abb533fdb32afd28b6e2458

commitb15c35ea952308f6236bdb8c5f1a094ca653a3f5 authorBryan O'Sullivan <bos@serpentine.com> dateTue 3 Mar 2009, 08:18 (18 years ago) parent35bd7d2
2 files changed+48−6
Data/Text/Lazy.hs+40−2 tests/Properties.hs+8−4
Data/Text/Lazy.hs+40−2
@@ -96,8 +96,8 @@ module Data.Text.Lazy
9696 -- ** Breaking strings
9797 , take
9898 , drop
99− -- , takeWhile
100− -- , dropWhile
99+ , takeWhile
100+ , dropWhile
101101 , splitAt
102102 -- , span
103103 -- , break
@@ -536,6 +536,44 @@ drop i t0
536536 unstream (S.drop n (stream t)) = drop n t
537537 #-}
538538
539+-- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'Text', returns
540+-- the longest prefix (possibly empty) of elements that satisfy @p@.
541+-- This function is subject to array fusion.
542+takeWhile :: (Char -> Bool) -> Text -> Text
543+takeWhile p t0 = takeWhile' t0
544+ where takeWhile' Empty = Empty
545+ takeWhile' (Chunk t ts) =
546+ case T.findIndex (not . p) t of
547+ Just n | n > 0 -> Chunk (T.take n t) Empty
548+ | otherwise -> Empty
549+ Nothing -> Chunk t (takeWhile' ts)
550+{-# INLINE [1] takeWhile #-}
551+
552+{-# RULES
553+"LAZY TEXT takeWhile -> fused" [~1] forall p t.
554+ takeWhile p t = unstream (S.takeWhile p (stream t))
555+"LAZY TEXT takeWhile -> unfused" [1] forall p t.
556+ unstream (S.takeWhile p (stream t)) = takeWhile p t
557+ #-}
558+
559+-- | /O(n)/ 'dropWhile' @p@ @xs@ returns the suffix remaining after
560+-- 'takeWhile' @p@ @xs@. This function is subject to array fusion.
561+dropWhile :: (Char -> Bool) -> Text -> Text
562+dropWhile p t0 = dropWhile' t0
563+ where dropWhile' Empty = Empty
564+ dropWhile' (Chunk t ts) =
565+ case T.findIndex (not . p) t of
566+ Just n -> Chunk (T.drop n t) ts
567+ Nothing -> dropWhile' ts
568+{-# INLINE [1] dropWhile #-}
569+
570+{-# RULES
571+"LAZY TEXT dropWhile -> fused" [~1] forall p t.
572+ dropWhile p t = unstream (S.dropWhile p (stream t))
573+"LAZY TEXT dropWhile -> unfused" [1] forall p t.
574+ unstream (S.dropWhile p (stream t)) = dropWhile p t
575+ #-}
576+
539577-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
540578-- prefix of @t@ of length @n@, and whose second is the remainder of
541579-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
tests/Properties.hs+8−4
@@ -221,10 +221,12 @@ prop_TL_take n = L.take n `eqP` (unpackT . TL.take (fromIntegral n)
221221prop_S_drop n = L.drop n `eqP` (unpackT . S.drop n)
222222prop_T_drop n = L.drop n `eqP` (unpackT . T.drop n)
223223prop_TL_drop n = L.drop n `eqP` (unpackT . TL.drop n)
224+prop_S_takeWhile p = L.takeWhile p `eqP` (unpackT . S.takeWhile p)
224225prop_T_takeWhile p = L.takeWhile p `eqP` (unpackT . T.takeWhile p)
225−prop_T_takeWhileS p = L.takeWhile p `eqP` (unpackT . S.unstream . S.takeWhile p . S.stream)
226+prop_TL_takeWhile p = L.takeWhile p `eqP` (unpackT . TL.takeWhile p)
227+prop_S_dropWhile p = L.dropWhile p `eqP` (unpackT . S.dropWhile p)
226228prop_T_dropWhile p = L.dropWhile p `eqP` (unpackT . T.dropWhile p)
227−prop_T_dropWhileS p = L.dropWhile p `eqP` (unpackT . S.unstream . S.dropWhile p . S.stream)
229+prop_TL_dropWhile p = L.dropWhile p `eqP` (unpackT . S.dropWhile p)
228230prop_T_splitAt n = L.splitAt n `eqP` (unpack2 . T.splitAt n)
229231prop_TL_splitAt n = L.splitAt n `eqP` (unpack2 . TL.splitAt n)
230232prop_T_span p = L.span p `eqP` (unpack2 . T.span p)
@@ -418,10 +420,12 @@ tests = [
418420 ("prop_S_drop", mytest prop_S_drop),
419421 ("prop_T_drop", mytest prop_T_drop),
420422 ("prop_TL_drop", mytest prop_TL_drop),
423+ ("prop_S_takeWhile", mytest prop_S_takeWhile),
421424 ("prop_T_takeWhile", mytest prop_T_takeWhile),
422− ("prop_T_takeWhileS", mytest prop_T_takeWhileS),
425+ ("prop_TL_takeWhile", mytest prop_TL_takeWhile),
426+ ("prop_S_dropWhile", mytest prop_S_dropWhile),
423427 ("prop_T_dropWhile", mytest prop_T_dropWhile),
424− ("prop_T_dropWhileS", mytest prop_T_dropWhileS),
428+ ("prop_TL_dropWhile", mytest prop_TL_dropWhile),
425429 ("prop_T_splitAt", mytest prop_T_splitAt),
426430 ("prop_T_span", mytest prop_T_span),
427431 ("prop_T_break", mytest prop_T_break),