on master help sign in
Write a dropAfter function.

--HG-- extra : convert_revision : 49f5d8bd305d44b61383260733cc647639beb247

commit51d643b430130e26d310407cddd373fa9d25cee9 authorBryan O'Sullivan <bos@serpentine.com> dateSat 4 Jul 2009, 05:54 (17 years ago) parent377118a
2 files changed+24−1
Data/Text.hs+20−1 tests/Properties.hs+4
Data/Text.hs+20−1
@@ -102,6 +102,7 @@ module Data.Text
102102 , drop
103103 , takeWhile
104104 , dropWhile
105+ , dropAfter
105106 , splitAt
106107 , span
107108 , break
@@ -172,7 +173,7 @@ import Data.Text.Fusion (stream, reverseStream, unstream)
172173
173174import Data.Text.Internal (Text(..), empty, text, textP)
174175import qualified Prelude as P
175−import Data.Text.Unsafe (iter, iter_, unsafeHead, unsafeTail)
176+import Data.Text.Unsafe (iter, iter_, reverseIter, unsafeHead, unsafeTail)
176177import Data.Text.UnsafeChar (unsafeChr)
177178import qualified Data.Text.Encoding.Utf16 as U16
178179
@@ -708,6 +709,24 @@ dropWhile p t@(Text arr off len) = loop 0 0
708709 unstream (S.dropWhile p (stream t)) = dropWhile p t
709710 #-}
710711
712+-- | /O(n)/ 'dropAfter' @p@ @t@ returns the prefix remaining after
713+-- dropping characters that fail the predicate @p@ from the end of
714+-- @t@. This function is subject to array fusion.
715+dropAfter :: (Char -> Bool) -> Text -> Text
716+dropAfter p t@(Text arr off len) = loop (len-1) len
717+ where loop !i !l | l <= 0 = empty
718+ | p c = loop (i+d) (l+d)
719+ | otherwise = Text arr off l
720+ where (c,d) = reverseIter t i
721+{-# INLINE [1] dropAfter #-}
722+
723+{-# RULES
724+"TEXT dropAfter -> fused" [~1] forall p t.
725+ dropAfter p t = S.reverse (S.dropWhile p (S.reverseStream t))
726+"TEXT dropAfter -> unfused" [1] forall p t.
727+ S.reverse (S.dropWhile p (S.reverseStream t)) = dropAfter p t
728+ #-}
729+
711730-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
712731-- prefix of @t@ of length @n@, and whose second is the remainder of
713732-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
tests/Properties.hs+4
@@ -248,6 +248,8 @@ prop_TL_takeWhile p = L.takeWhile p `eqP` (unpackS . TL.takeWhile p)
248248prop_S_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
249249prop_T_dropWhile p = L.dropWhile p `eqP` (unpackS . T.dropWhile p)
250250prop_TL_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
251+prop_S_dropAfter p = T.dropAfter p `eq` (S.reverse . S.dropWhile p . S.reverseStream)
252+prop_T_dropAfter p = (T.reverse . T.dropWhile p . T.reverse) `eq` T.dropAfter p
251253prop_T_splitAt n = L.splitAt n `eqP` (unpack2 . T.splitAt n)
252254prop_TL_splitAt n = L.splitAt n `eqP` (unpack2 . TL.splitAt (fromIntegral n))
253255prop_T_span p = L.span p `eqP` (unpack2 . T.span p)
@@ -487,6 +489,8 @@ tests = [
487489 ("prop_S_dropWhile", mytest prop_S_dropWhile),
488490 ("prop_T_dropWhile", mytest prop_T_dropWhile),
489491 ("prop_TL_dropWhile", mytest prop_TL_dropWhile),
492+ ("prop_S_dropAfter", mytest prop_S_dropAfter),
493+ ("prop_T_dropAfter", mytest prop_T_dropAfter),
490494 ("prop_T_splitAt", mytest prop_T_splitAt),
491495 ("prop_T_span", mytest prop_T_span),
492496 ("prop_TL_span", mytest prop_TL_span),