@@ -123,6 +123,7 @@ module Data.Text
123 -- ** Breaking strings
123 -- ** Breaking strings
126 , takeWhile
127 , takeWhile
127 , dropWhile
128 , dropWhile
128 , dropWhileEnd
129 , dropWhileEnd
@@ -214,7 +215,7 @@ import Data.Text.Internal.Private (span_)
214import Data.Text.Internal (Text(..), empty, firstf, safe, text, textP)
215import Data.Text.Internal (Text(..), empty, firstf, safe, text, textP)
215import qualified Prelude as P
216import qualified Prelude as P
216import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
217import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
217− unsafeHead, unsafeTail)
218+ reverseIter_, unsafeHead, unsafeTail)
218import Data.Text.Internal.Unsafe.Char (unsafeChr)
219import Data.Text.Internal.Unsafe.Char (unsafeChr)
219import qualified Data.Text.Internal.Functions as F
220import qualified Data.Text.Internal.Functions as F
220import qualified Data.Text.Internal.Encoding.Utf16 as U16
221import qualified Data.Text.Internal.Encoding.Utf16 as U16
@@ -1038,6 +1039,23 @@ drop n t@(Text arr off len)
1038 unstream (S.drop n (stream t)) = drop n t
1039 unstream (S.drop n (stream t)) = drop n t
1042+-- | /O(n)/ 'dropEnd' @n@ @t@ returns the prefix remaining after
1043+-- dropping @n@ characters from the end of @t@.
1047+-- > dropEnd 3 "foobar" == "foo"
1048+dropEnd :: Int -> Text -> Text
1049+dropEnd n t@(Text arr off len)
1052+ | otherwise = loop (len-1) n
1055+ | m <= 1 = Text arr off i
1056+ | otherwise = loop (i+d) (m-1)
1057+ where d = reverseIter_ t i
1041-- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'Text',
1059-- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'Text',
1042-- returns the longest prefix (possibly empty) of elements that
1060-- returns the longest prefix (possibly empty) of elements that
1043-- satisfy @p@. Subject to fusion.
1061-- satisfy @p@. Subject to fusion.