on master help sign in
Implement and test lazy scanr and reverse
1a7653aBryan O'Sullivan
Data/Text.hs+1−1
@@ -500,7 +500,7 @@ scanl1 f t | null t = empty
500
500
501-- | /O(n)/ 'scanr' is the right-to-left dual of 'scanl'.
501-- | /O(n)/ 'scanr' is the right-to-left dual of 'scanl'.
502--
502--
503−-- > scanr f v t == reverse (scanl (flip f) v t)
503+-- > scanr f v == reverse . scanl (flip f) v . reverse
504scanr :: (Char -> Char -> Char) -> Char -> Text -> Text
504scanr :: (Char -> Char -> Char) -> Char -> Text -> Text
505scanr f z = S.reverse . S.reverseScanr f z . reverseStream
505scanr f z = S.reverse . S.reverseScanr f z . reverseStream
506{-# INLINE scanr #-}
506{-# INLINE scanr #-}
Data/Text/Lazy.hs+14−2
@@ -58,7 +58,7 @@ module Data.Text.Lazy
58 , intercalate
58 , intercalate
59 , intersperse
59 , intersperse
60 , transpose
60 , transpose
61− -- , reverse
61+ , reverse
62
62
63 -- * Folds
63 -- * Folds
64 , foldl
64 , foldl
@@ -81,7 +81,7 @@ module Data.Text.Lazy
81 -- ** Scans
81 -- ** Scans
82 , scanl
82 , scanl
83 , scanl1
83 , scanl1
84− -- , scanr
84+ , scanr
85 -- , scanr1
85 -- , scanr1
86
86
87 -- ** Accumulating maps
87 -- ** Accumulating maps
@@ -363,6 +363,12 @@ transpose ts = L.map (\ss -> Chunk (T.pack ss) Empty)
363 (L.transpose (L.map unpack ts))
363 (L.transpose (L.map unpack ts))
364-- TODO: make this fast
364-- TODO: make this fast
365
365
366+-- | /O(n)/ 'reverse' @t@ returns the elements of @t@ in reverse order.
367+reverse :: Text -> Text
368+reverse = rev Empty
369+ where rev a Empty = a
370+ rev a (Chunk t ts) = rev (Chunk (T.reverse t) a) ts
371+
366-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
372-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
367-- (typically the left-identity of the operator), and a 'Text',
373-- (typically the left-identity of the operator), and a 'Text',
368-- reduces the 'Text' using the binary operator, from left to right.
374-- reduces the 'Text' using the binary operator, from left to right.
@@ -466,6 +472,12 @@ scanl1 f t0 = case uncons t0 of
466 Just (t,ts) -> scanl f t ts
472 Just (t,ts) -> scanl f t ts
467{-# INLINE scanl1 #-}
473{-# INLINE scanl1 #-}
468
474
475+-- | /O(n)/ 'scanr' is the right-to-left dual of 'scanl'.
476+--
477+-- > scanr f v == reverse . scanl (flip f) v . reverse
478+scanr :: (Char -> Char -> Char) -> Char -> Text -> Text
479+scanr f v = reverse . scanl (flip f) v . reverse
480+
469-- | /O(n)/ Like a combination of 'map' and 'foldl'. Applies a
481-- | /O(n)/ Like a combination of 'map' and 'foldl'. Applies a
470-- function to each element of a 'Text', passing an accumulating
482-- function to each element of a 'Text', passing an accumulating
471-- parameter from left to right, and returns a final 'Text'.
483-- parameter from left to right, and returns a final 'Text'.
tests/Properties.hs+4
@@ -159,6 +159,7 @@ prop_TL_intersperse c = L.intersperse c `eqP` (unpackT . TL.intersperse c)
159prop_T_transpose = L.transpose `eq` (map unpackT . T.transpose . map T.pack)
159prop_T_transpose = L.transpose `eq` (map unpackT . T.transpose . map T.pack)
160prop_TL_transpose = L.transpose `eq` (map unpackT . TL.transpose . map TL.pack)
160prop_TL_transpose = L.transpose `eq` (map unpackT . TL.transpose . map TL.pack)
161prop_T_reverse = L.reverse `eqP` (unpackT . T.reverse)
161prop_T_reverse = L.reverse `eqP` (unpackT . T.reverse)
162+prop_TL_reverse = L.reverse `eqP` (unpackT . TL.reverse)
162prop_T_reverse_short n = L.reverse `eqP` (unpackT . S.reverse . shorten n . S.stream)
163prop_T_reverse_short n = L.reverse `eqP` (unpackT . S.reverse . shorten n . S.stream)
163
164
164prop_T_foldl f z = L.foldl f z `eqP` (T.foldl f z)
165prop_T_foldl f z = L.foldl f z `eqP` (T.foldl f z)
@@ -198,6 +199,7 @@ prop_TL_scanl f z = L.scanl f z `eqP` (unpackT . TL.scanl f z)
198prop_T_scanl1 f = L.scanl1 f `eqP` (unpackT . T.scanl1 f)
199prop_T_scanl1 f = L.scanl1 f `eqP` (unpackT . T.scanl1 f)
199prop_TL_scanl1 f = L.scanl1 f `eqP` (unpackT . TL.scanl1 f)
200prop_TL_scanl1 f = L.scanl1 f `eqP` (unpackT . TL.scanl1 f)
200prop_T_scanr f z = L.scanr f z `eqP` (unpackT . T.scanr f z)
201prop_T_scanr f z = L.scanr f z `eqP` (unpackT . T.scanr f z)
202+prop_TL_scanr f z = L.scanr f z `eqP` (unpackT . TL.scanr f z)
201prop_T_scanr1 f = L.scanr1 f `eqP` (unpackT . T.scanr1 f)
203prop_T_scanr1 f = L.scanr1 f `eqP` (unpackT . T.scanr1 f)
202
204
203prop_T_mapAccumL f z = L.mapAccumL f z `eqP` (second unpackT . T.mapAccumL f z)
205prop_T_mapAccumL f z = L.mapAccumL f z `eqP` (second unpackT . T.mapAccumL f z)
@@ -392,6 +394,7 @@ tests = [
392 ("prop_T_transpose", mytest prop_T_transpose),
394 ("prop_T_transpose", mytest prop_T_transpose),
393 ("prop_TL_transpose", mytest prop_TL_transpose),
395 ("prop_TL_transpose", mytest prop_TL_transpose),
394 ("prop_T_reverse", mytest prop_T_reverse),
396 ("prop_T_reverse", mytest prop_T_reverse),
397+ ("prop_TL_reverse", mytest prop_TL_reverse),
395 ("prop_T_reverse_short", mytest prop_T_reverse_short),
398 ("prop_T_reverse_short", mytest prop_T_reverse_short),
396
399
397 ("prop_T_foldl", mytest prop_T_foldl),
400 ("prop_T_foldl", mytest prop_T_foldl),
@@ -425,6 +428,7 @@ tests = [
425 ("prop_T_scanl1", mytest prop_T_scanl1),
428 ("prop_T_scanl1", mytest prop_T_scanl1),
426 ("prop_TL_scanl1", mytest prop_TL_scanl1),
429 ("prop_TL_scanl1", mytest prop_TL_scanl1),
427 ("prop_T_scanr", mytest prop_T_scanr),
430 ("prop_T_scanr", mytest prop_T_scanr),
431+ ("prop_TL_scanr", mytest prop_TL_scanr),
428 ("prop_T_scanr1", mytest prop_T_scanr1),
432 ("prop_T_scanr1", mytest prop_T_scanr1),
429
433
430 ("prop_T_mapAccumL", mytest prop_T_mapAccumL),
434 ("prop_T_mapAccumL", mytest prop_T_mapAccumL),