Commits

Bryan O'Sullivan committed 6f2b209

Implement lazy takeEnd

Comments (0)

Files changed (2)

Data/Text/Lazy.hs

 
     -- ** Breaking strings
     , take
+    , takeEnd
     , drop
     , dropEnd
     , takeWhile
     unstream (S.take n (stream t)) = take n t
   #-}
 
+-- | /O(n)/ 'takeEnd' @n@ @t@ returns the suffix remaining after
+-- taking @n@ characters from the end of @t@.
+--
+-- Examples:
+--
+-- > takeEnd 3 "foobar" == "bar"
+takeEnd :: Int64 -> Text -> Text
+takeEnd n t0
+    | n <= 0    = empty
+    | otherwise = fromChunks . L.reverse .
+                  takeChunk n . L.reverse . toChunks $ t0
+  where takeChunk _ [] = []
+        takeChunk i (t:ts)
+          | i <= l    = [T.takeEnd (fromIntegral i) t]
+          | otherwise = t : takeChunk (i-l) ts
+          where l = fromIntegral (T.length t)
+
 -- | /O(n)/ 'drop' @n@, applied to a 'Text', returns the suffix of the
 -- 'Text' after the first @n@ characters, or the empty 'Text' if @n@
 -- is greater than the length of the 'Text'. Subject to fusion.

tests/Tests/Properties.hs

 t_takeEnd n       = (L.reverse . L.take n . L.reverse) `eqP`
                     (unpackS . T.takeEnd n)
 tl_take n         = L.take n      `eqP` (unpackS . TL.take (fromIntegral n))
+tl_takeEnd n      = (L.reverse . L.take (fromIntegral n) . L.reverse) `eqP`
+                    (unpackS . TL.takeEnd n)
 s_drop n          = L.drop n      `eqP` (unpackS . S.drop n)
 s_drop_s m        = L.drop n      `eqP` (unpackS . S.unstream . S.drop n)
   where n = small m
         testProperty "t_take" t_take,
         testProperty "t_takeEnd" t_takeEnd,
         testProperty "tl_take" tl_take,
+        testProperty "tl_takeEnd" tl_takeEnd,
         testProperty "s_drop" s_drop,
         testProperty "s_drop_s" s_drop_s,
         testProperty "sf_drop" sf_drop,