on master help sign in
Merge pull request #135 from paulcapron/master
8aef850Bryan O'Sullivan
Data/Text.hs+22
@@ -129,6 +129,7 @@ module Data.Text
129 , drop
129 , drop
130 , dropEnd
130 , dropEnd
131 , takeWhile
131 , takeWhile
132+ , takeWhileEnd
132 , dropWhile
133 , dropWhile
133 , dropWhileEnd
134 , dropWhileEnd
134 , dropAround
135 , dropAround
@@ -1144,6 +1145,27 @@ takeWhile p t@(Text arr off len) = loop 0
1144 unstream (S.takeWhile p (stream t)) = takeWhile p t
1145 unstream (S.takeWhile p (stream t)) = takeWhile p t
1145 #-}
1146 #-}
1146
1147
1148+-- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text',
1149+-- returns the longest suffix (possibly empty) of elements that
1150+-- satisfy @p@. Subject to fusion.
1151+-- Examples:
1152+--
1153+-- > takeWhileEnd (=='o') "foo" == "oo"
1154+takeWhileEnd :: (Char -> Bool) -> Text -> Text
1155+takeWhileEnd p t@(Text arr off len) = loop (len-1) len
1156+ where loop !i !l | l <= 0 = t
1157+ | p c = loop (i+d) (l+d)
1158+ | otherwise = text arr (off+l) (len-l)
1159+ where (c,d) = reverseIter t i
1160+{-# INLINE [1] takeWhileEnd #-}
1161+
1162+{-# RULES
1163+"TEXT takeWhileEnd -> fused" [~1] forall p t.
1164+ takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))
1165+"TEXT takeWhileEnd -> unfused" [1] forall p t.
1166+ S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t
1167+ #-}
1168+
1147-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1169-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1148-- 'takeWhile' @p@ @t@. Subject to fusion.
1170-- 'takeWhile' @p@ @t@. Subject to fusion.
1149dropWhile :: (Char -> Bool) -> Text -> Text
1171dropWhile :: (Char -> Bool) -> Text -> Text
Data/Text/Lazy.hs+15
@@ -140,6 +140,7 @@ module Data.Text.Lazy
140 , drop
140 , drop
141 , dropEnd
141 , dropEnd
142 , takeWhile
142 , takeWhile
143+ , takeWhileEnd
143 , dropWhile
144 , dropWhile
144 , dropWhileEnd
145 , dropWhileEnd
145 , dropAround
146 , dropAround
@@ -1139,6 +1140,20 @@ takeWhile p t0 = takeWhile' t0
1139"LAZY TEXT takeWhile -> unfused" [1] forall p t.
1140"LAZY TEXT takeWhile -> unfused" [1] forall p t.
1140 unstream (S.takeWhile p (stream t)) = takeWhile p t
1141 unstream (S.takeWhile p (stream t)) = takeWhile p t
1141 #-}
1142 #-}
1143+-- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text',
1144+-- returns the longest suffix (possibly empty) of elements that
1145+-- satisfy @p@.
1146+-- Examples:
1147+--
1148+-- > takeWhileEnd (=='o') "foo" == "oo"
1149+takeWhileEnd :: (Char -> Bool) -> Text -> Text
1150+takeWhileEnd p = takeChunk empty . L.reverse . toChunks
1151+ where takeChunk acc [] = acc
1152+ takeChunk acc (t:ts) = if T.length t' < T.length t
1153+ then (Chunk t' acc)
1154+ else takeChunk (Chunk t' acc) ts
1155+ where t' = T.takeWhileEnd p t
1156+{-# INLINE takeWhileEnd #-}
1142
1157
1143-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1158-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1144-- 'takeWhile' @p@ @t@. Subject to fusion.
1159-- 'takeWhile' @p@ @t@. Subject to fusion.
tests/Tests/Properties.hs+6
@@ -516,6 +516,10 @@ sf_takeWhile q p = (L.takeWhile p . L.filter q) `eqP`
516 (unpackS . S.takeWhile p . S.filter q)
516 (unpackS . S.takeWhile p . S.filter q)
517t_takeWhile p = L.takeWhile p `eqP` (unpackS . T.takeWhile p)
517t_takeWhile p = L.takeWhile p `eqP` (unpackS . T.takeWhile p)
518tl_takeWhile p = L.takeWhile p `eqP` (unpackS . TL.takeWhile p)
518tl_takeWhile p = L.takeWhile p `eqP` (unpackS . TL.takeWhile p)
519+t_takeWhileEnd p = (L.reverse . L.takeWhile p . L.reverse) `eqP`
520+ (unpackS . T.takeWhileEnd p)
521+tl_takeWhileEnd p = (L.reverse . L.takeWhile p . L.reverse) `eqP`
522+ (unpackS . TL.takeWhileEnd p)
519s_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
523s_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
520s_dropWhile_s p = L.dropWhile p `eqP` (unpackS . S.unstream . S.dropWhile p)
524s_dropWhile_s p = L.dropWhile p `eqP` (unpackS . S.unstream . S.dropWhile p)
521sf_dropWhile q p = (L.dropWhile p . L.filter q) `eqP`
525sf_dropWhile q p = (L.dropWhile p . L.filter q) `eqP`
@@ -1142,6 +1146,8 @@ tests =
1142 testProperty "sf_takeWhile" sf_takeWhile,
1146 testProperty "sf_takeWhile" sf_takeWhile,
1143 testProperty "t_takeWhile" t_takeWhile,
1147 testProperty "t_takeWhile" t_takeWhile,
1144 testProperty "tl_takeWhile" tl_takeWhile,
1148 testProperty "tl_takeWhile" tl_takeWhile,
1149+ testProperty "t_takeWhileEnd" t_takeWhileEnd,
1150+ testProperty "tl_takeWhileEnd" tl_takeWhileEnd,
1145 testProperty "sf_dropWhile" sf_dropWhile,
1151 testProperty "sf_dropWhile" sf_dropWhile,
1146 testProperty "s_dropWhile" s_dropWhile,
1152 testProperty "s_dropWhile" s_dropWhile,
1147 testProperty "s_dropWhile_s" s_dropWhile_s,
1153 testProperty "s_dropWhile_s" s_dropWhile_s,