on master help sign in
Implement and test lazy drop

--HG-- extra : convert_revision : 094d6e0b44b4e56e75c0cdbf52cdd0973fefe4d0

commit35bd7d25341904362c55170ed24b6170ab662082 authorBryan O'Sullivan <bos@serpentine.com> dateTue 3 Mar 2009, 08:09 (18 years ago) parent73f9b61
3 files changed+30−3
Data/Text/Fusion/Common.hs+3−2 Data/Text/Lazy.hs+23−1 tests/Properties.hs+4
Data/Text/Fusion/Common.hs+3−2
@@ -544,8 +544,9 @@ take n0 (Stream next0 s0 len) = Stream next (n0 :!: s0) len
544544-- | /O(n)/ drop n, applied to a stream, returns the suffix of the
545545-- stream of length @n@, or the empty stream if @n@ is greater than the
546546-- length of the stream.
547−drop :: Int -> Stream Char -> Stream Char
548−drop n0 (Stream next0 s0 len) = Stream next (Just ((max 0 n0)) :!: s0) (len - n0)
547+drop :: Integral a => a -> Stream Char -> Stream Char
548+drop n0 (Stream next0 s0 len) =
549+ Stream next (Just ((max 0 n0)) :!: s0) (len - fromIntegral n0)
549550 where
550551 {-# INLINE next #-}
551552 next (Just !n :!: s)
Data/Text/Lazy.hs+23−1
@@ -95,7 +95,7 @@ module Data.Text.Lazy
9595
9696 -- ** Breaking strings
9797 , take
98− -- , drop
98+ , drop
9999 -- , takeWhile
100100 -- , dropWhile
101101 , splitAt
@@ -514,6 +514,28 @@ take i t0 = take' i t0
514514 unstream (S.take n (stream t)) = take n t
515515 #-}
516516
517+-- | /O(n)/ 'drop' @n@, applied to a 'Text', returns the suffix of the
518+-- 'Text' of length @n@, or the empty 'Text' if @n@ is greater than the
519+-- length of the 'Text'. Subject to fusion.
520+drop :: Int -> Text -> Text
521+drop i t0
522+ | i <= 0 = t0
523+ | otherwise = drop' i t0
524+ where drop' 0 ts = ts
525+ drop' _ Empty = Empty
526+ drop' n (Chunk t ts)
527+ | n < len = Chunk (T.drop (fromIntegral n) t) ts
528+ | otherwise = drop' (n - len) ts
529+ where len = fromIntegral (T.length t)
530+{-# INLINE [1] drop #-}
531+
532+{-# RULES
533+"LAZY TEXT drop -> fused" [~1] forall n t.
534+ drop n t = unstream (S.drop n (stream t))
535+"LAZY TEXT drop -> unfused" [1] forall n t.
536+ unstream (S.drop n (stream t)) = drop n t
537+ #-}
538+
517539-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
518540-- prefix of @t@ of length @n@, and whose second is the remainder of
519541-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
tests/Properties.hs+4
@@ -218,7 +218,9 @@ unpack2 = unpackT *** unpackT
218218prop_S_take n = L.take n `eqP` (unpackT . S.take n)
219219prop_T_take n = L.take n `eqP` (unpackT . T.take n)
220220prop_TL_take n = L.take n `eqP` (unpackT . TL.take (fromIntegral n))
221+prop_S_drop n = L.drop n `eqP` (unpackT . S.drop n)
221222prop_T_drop n = L.drop n `eqP` (unpackT . T.drop n)
223+prop_TL_drop n = L.drop n `eqP` (unpackT . TL.drop n)
222224prop_T_takeWhile p = L.takeWhile p `eqP` (unpackT . T.takeWhile p)
223225prop_T_takeWhileS p = L.takeWhile p `eqP` (unpackT . S.unstream . S.takeWhile p . S.stream)
224226prop_T_dropWhile p = L.dropWhile p `eqP` (unpackT . T.dropWhile p)
@@ -413,7 +415,9 @@ tests = [
413415 ("prop_S_take", mytest prop_S_take),
414416 ("prop_T_take", mytest prop_T_take),
415417 ("prop_TL_take", mytest prop_TL_take),
418+ ("prop_S_drop", mytest prop_S_drop),
416419 ("prop_T_drop", mytest prop_T_drop),
420+ ("prop_TL_drop", mytest prop_TL_drop),
417421 ("prop_T_takeWhile", mytest prop_T_takeWhile),
418422 ("prop_T_takeWhileS", mytest prop_T_takeWhileS),
419423 ("prop_T_dropWhile", mytest prop_T_dropWhile),