on master help sign in
Implement and test lazy drop
35bd7d2Bryan O'Sullivan
Data/Text/Fusion/Common.hs+3−2
@@ -544,8 +544,9 @@ take n0 (Stream next0 s0 len) = Stream next (n0 :!: s0) len
544-- | /O(n)/ drop n, applied to a stream, returns the suffix of the
544-- | /O(n)/ drop n, applied to a stream, returns the suffix of the
545-- stream of length @n@, or the empty stream if @n@ is greater than the
545-- stream of length @n@, or the empty stream if @n@ is greater than the
546-- length of the stream.
546-- length of the stream.
547−drop :: Int -> Stream Char -> Stream Char
547+drop :: Integral a => a -> Stream Char -> Stream Char
548−drop n0 (Stream next0 s0 len) = Stream next (Just ((max 0 n0)) :!: s0) (len - n0)
548+drop n0 (Stream next0 s0 len) =
549+ Stream next (Just ((max 0 n0)) :!: s0) (len - fromIntegral n0)
549 where
550 where
550 {-# INLINE next #-}
551 {-# INLINE next #-}
551 next (Just !n :!: s)
552 next (Just !n :!: s)
Data/Text/Lazy.hs+23−1
@@ -95,7 +95,7 @@ module Data.Text.Lazy
95
95
96 -- ** Breaking strings
96 -- ** Breaking strings
97 , take
97 , take
98− -- , drop
98+ , drop
99 -- , takeWhile
99 -- , takeWhile
100 -- , dropWhile
100 -- , dropWhile
101 , splitAt
101 , splitAt
@@ -514,6 +514,28 @@ take i t0 = take' i t0
514 unstream (S.take n (stream t)) = take n t
514 unstream (S.take n (stream t)) = take n t
515 #-}
515 #-}
516
516
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+
517-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
539-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
518-- prefix of @t@ of length @n@, and whose second is the remainder of
540-- prefix of @t@ of length @n@, and whose second is the remainder of
519-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
541-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
tests/Properties.hs+4
@@ -218,7 +218,9 @@ unpack2 = unpackT *** unpackT
218prop_S_take n = L.take n `eqP` (unpackT . S.take n)
218prop_S_take n = L.take n `eqP` (unpackT . S.take n)
219prop_T_take n = L.take n `eqP` (unpackT . T.take n)
219prop_T_take n = L.take n `eqP` (unpackT . T.take n)
220prop_TL_take n = L.take n `eqP` (unpackT . TL.take (fromIntegral n))
220prop_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)
221prop_T_drop n = L.drop n `eqP` (unpackT . T.drop n)
222prop_T_drop n = L.drop n `eqP` (unpackT . T.drop n)
223+prop_TL_drop n = L.drop n `eqP` (unpackT . TL.drop n)
222prop_T_takeWhile p = L.takeWhile p `eqP` (unpackT . T.takeWhile p)
224prop_T_takeWhile p = L.takeWhile p `eqP` (unpackT . T.takeWhile p)
223prop_T_takeWhileS p = L.takeWhile p `eqP` (unpackT . S.unstream . S.takeWhile p . S.stream)
225prop_T_takeWhileS p = L.takeWhile p `eqP` (unpackT . S.unstream . S.takeWhile p . S.stream)
224prop_T_dropWhile p = L.dropWhile p `eqP` (unpackT . T.dropWhile p)
226prop_T_dropWhile p = L.dropWhile p `eqP` (unpackT . T.dropWhile p)
@@ -413,7 +415,9 @@ tests = [
413 ("prop_S_take", mytest prop_S_take),
415 ("prop_S_take", mytest prop_S_take),
414 ("prop_T_take", mytest prop_T_take),
416 ("prop_T_take", mytest prop_T_take),
415 ("prop_TL_take", mytest prop_TL_take),
417 ("prop_TL_take", mytest prop_TL_take),
418+ ("prop_S_drop", mytest prop_S_drop),
416 ("prop_T_drop", mytest prop_T_drop),
419 ("prop_T_drop", mytest prop_T_drop),
420+ ("prop_TL_drop", mytest prop_TL_drop),
417 ("prop_T_takeWhile", mytest prop_T_takeWhile),
421 ("prop_T_takeWhile", mytest prop_T_takeWhile),
418 ("prop_T_takeWhileS", mytest prop_T_takeWhileS),
422 ("prop_T_takeWhileS", mytest prop_T_takeWhileS),
419 ("prop_T_dropWhile", mytest prop_T_dropWhile),
423 ("prop_T_dropWhile", mytest prop_T_dropWhile),