on master help sign in
Add lazy justification.

--HG-- extra : convert_revision : 9f15afe427eda1a1e204076baa6f02b098189cf3

commitdf4e5e8545442214bd3b19eb585906caeca86bc7 authorBryan O'Sullivan <bos@serpentine.com> dateSun 16 Aug 2009, 03:59 (17 years ago) parent41d8407
4 files changed+78−23
Data/Text.hs+3−3 Data/Text/Fusion/Common.hs+11−10 Data/Text/Lazy.hs+53−3 tests/Properties.hs+11−7
Data/Text.hs+3−3
@@ -471,9 +471,9 @@ justifyLeft k c t
471471
472472{-# RULES
473473"TEXT justifyLeft -> fused" [~1] forall k c t.
474− justifyLeft k c t = unstream (S.justifyLeft k c (stream t))
474+ justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
475475"TEXT justifyLeft -> unfused" [1] forall k c t.
476− unstream (S.justifyLeft k c (stream t)) = justifyLeft k c t
476+ unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
477477 #-}
478478
479479-- | /O(n)/ Right-justify a string to the given length, using the
@@ -657,7 +657,7 @@ mapAccumR f s t = case uncons t of
657657-- | /O(n)/ 'replicate' @n@ @c@ is a 'Text' of length @n@ with @c@ the
658658-- value of every element. Subject to fusion.
659659replicate :: Int -> Char -> Text
660−replicate n c = unstream (S.replicate n c)
660+replicate n c = unstream (S.replicateI n c)
661661{-# INLINE replicate #-}
662662
663663-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
Data/Text/Fusion/Common.hs+11−10
@@ -42,7 +42,7 @@ module Data.Text.Fusion.Common
4242 , toUpper
4343
4444 -- ** Justification
45− , justifyLeft
45+ , justifyLeftI
4646
4747 -- * Folds
4848 , foldl
@@ -68,7 +68,7 @@ module Data.Text.Fusion.Common
6868 -- , mapAccumL
6969
7070 -- ** Generation and unfolding
71− , replicate
71+ , replicateI
7272 , unfoldr
7373 , unfoldrNI
7474
@@ -361,10 +361,11 @@ toLower :: Stream Char -> Stream Char
361361toLower = caseConvert lowerMapping
362362{-# INLINE [0] toLower #-}
363363
364−justifyLeft :: Int -> Char -> Stream Char -> Stream Char
365−justifyLeft k c (Stream next0 s0 len) = Stream next (s0 :!: S1 :!: 0) newLen
364+justifyLeftI :: Integral a => a -> Char -> Stream Char -> Stream Char
365+justifyLeftI k c (Stream next0 s0 len) = Stream next (s0 :!: S1 :!: 0) newLen
366366 where
367− newLen | k > len = k
367+ j = fromIntegral k
368+ newLen | j > len = j
368369 | otherwise = len
369370 next (s :!: S1 :!: n) =
370371 case next0 s of
@@ -375,7 +376,7 @@ justifyLeft k c (Stream next0 s0 len) = Stream next (s0 :!: S1 :!: 0) newLen
375376 | n < k = Yield c (s :!: S2 :!: n+1)
376377 | otherwise = Done
377378 {-# INLINE next #-}
378−{-# INLINE justifyLeft #-}
379+{-# INLINE [0] justifyLeftI #-}
379380
380381-- ----------------------------------------------------------------------------
381382-- * Reducing Streams (folds)
@@ -575,15 +576,15 @@ mapAccumL f z0 (Stream next0 s0 len) = Stream next (s0 :!: z0) len -- HINT depen
575576-- -----------------------------------------------------------------------------
576577-- ** Generating and unfolding streams
577578
578−replicate :: Int -> Char -> Stream Char
579−replicate n c
579+replicateI :: Integral a => a -> Char -> Stream Char
580+replicateI n c
580581 | n < 0 = empty
581− | otherwise = Stream next 0 n -- HINT maybe too low
582+ | otherwise = Stream next 0 (fromIntegral n) -- HINT maybe too low
582583 where
583584 {-# INLINE next #-}
584585 next i | i >= n = Done
585586 | otherwise = Yield c (i + 1)
586−{-# INLINE [0] replicate #-}
587+{-# INLINE [0] replicateI #-}
587588
588589-- | /O(n)/, where @n@ is the length of the result. The unfoldr function
589590-- is analogous to the List 'unfoldr'. unfoldr builds a stream
Data/Text/Lazy.hs+53−3
@@ -64,6 +64,11 @@ module Data.Text.Lazy
6464 , toLower
6565 , toUpper
6666
67+ -- ** Justification
68+ , justifyLeft
69+ , justifyRight
70+ , center
71+
6772 -- * Folds
6873 , foldl
6974 , foldl'
@@ -156,7 +161,7 @@ module Data.Text.Lazy
156161import Prelude (Char, Bool(..), Int, Maybe(..), String,
157162 Eq(..), Ord(..), Read(..), Show(..),
158163 (&&), (+), (-), (.), ($), (++),
159− flip, fromIntegral, not, otherwise)
164+ div, flip, fromIntegral, not, otherwise)
160165import qualified Prelude as P
161166import Data.Int (Int64)
162167import qualified Data.List as L
@@ -365,6 +370,51 @@ intersperse :: Char -> Text -> Text
365370intersperse c t = unstream (S.intersperse c (stream t))
366371{-# INLINE intersperse #-}
367372
373+-- | /O(n)/ Left-justify a string to the given length, using the
374+-- specified fill character on the right. Subject to fusion. Examples:
375+--
376+-- > justifyLeft 7 'x' "foo" == "fooxxxx"
377+-- > justifyLeft 3 'x' "foobar" == "foobar"
378+justifyLeft :: Int64 -> Char -> Text -> Text
379+justifyLeft k c t
380+ | len >= k = t
381+ | otherwise = t `append` replicate (k-len) c
382+ where len = length t
383+{-# INLINE [1] justifyLeft #-}
384+
385+{-# RULES
386+"TEXT justifyLeft -> fused" [~1] forall k c t.
387+ justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
388+"TEXT justifyLeft -> unfused" [1] forall k c t.
389+ unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
390+ #-}
391+
392+-- | /O(n)/ Right-justify a string to the given length, using the
393+-- specified fill character on the left. Examples:
394+--
395+-- > justifyRight 7 'x' "bar" == "xxxxbar"
396+-- > justifyRight 3 'x' "foobar" == "foobar"
397+justifyRight :: Int64 -> Char -> Text -> Text
398+justifyRight k c t
399+ | len >= k = t
400+ | otherwise = replicate (k-len) c `append` t
401+ where len = length t
402+{-# INLINE justifyRight #-}
403+
404+-- | /O(n)/ Center a string to the given length, using the
405+-- specified fill character on either side. Examples:
406+--
407+-- > center 8 'x' "HS" = "xxxHSxxx"
408+center :: Int64 -> Char -> Text -> Text
409+center k c t
410+ | len >= k = t
411+ | otherwise = replicate l c `append` t `append` replicate r c
412+ where len = length t
413+ d = k - len
414+ r = d `div` 2
415+ l = d - r
416+{-# INLINE center #-}
417+
368418-- | /O(n)/ The 'transpose' function transposes the rows and columns
369419-- of its 'Text' argument. Note that this function uses 'pack',
370420-- 'unpack', and the list version of transpose, and is thus not very
@@ -565,8 +615,8 @@ mapAccumR f s t = case uncons t of
565615
566616-- | /O(n)/ 'replicate' @n@ @c@ is a 'Text' of length @n@ with @c@ the
567617-- value of every element.
568−replicate :: Int -> Char -> Text
569−replicate n c = unstream (S.replicate n c)
618+replicate :: Int64 -> Char -> Text
619+replicate n c = unstream (S.replicateI n c)
570620{-# INLINE replicate #-}
571621
572622-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
tests/Properties.hs+11−7
@@ -232,14 +232,16 @@ t_toUpper_length t = T.length (T.toUpper t) >= T.length t
232232t_toUpper_upper t = p (T.toUpper t) >= p t
233233 where p = T.length . T.filter isUpper
234234
235−justifyLeft k c s = s ++ replicate (k - length s) c
235+justifyLeft k c s = s ++ replicate (k - length s) c
236+justifyRight m n s = replicate (m - length s) n ++ s
236237
237−s_justifyLeft k c = justifyLeft k c `eqP` (unpackS . S.justifyLeft k c)
238+s_justifyLeft k c = justifyLeft k c `eqP` (unpackS . S.justifyLeftI k c)
238239sf_justifyLeft p k c =
239− (justifyLeft k c . L.filter p) `eqP` (unpackS . S.justifyLeft k c . S.filter p)
240+ (justifyLeft k c . L.filter p) `eqP` (unpackS . S.justifyLeftI k c . S.filter p)
240241t_justifyLeft k c = justifyLeft k c `eqP` (unpackS . T.justifyLeft k c)
241−t_justifyRight k c = jr k c `eqP` (unpackS . T.justifyRight k c)
242− where jr m n s = replicate (m - length s) n ++ s
242+tl_justifyLeft k c = justifyLeft k c `eqP` (unpackS . TL.justifyLeft (fromIntegral k) c)
243+t_justifyRight k c = justifyRight k c `eqP` (unpackS . T.justifyRight k c)
244+tl_justifyRight k c = justifyRight k c `eqP` (unpackS . TL.justifyRight (fromIntegral k) c)
243245
244246sf_foldl p f z = (L.foldl f z . L.filter p) `eqP` (S.foldl f z . S.filter p)
245247 where _types = f :: Char -> Char -> Char
@@ -308,7 +310,7 @@ tl_mapAccumR f z = unsquare (L.mapAccumR f z `eqP` (second unpackS . TL.mapAcc
308310 where _types = f :: Int -> Char -> (Int,Char)
309311
310312t_replicate n = L.replicate n `eq` (unpackS . T.replicate n)
311−tl_replicate n = L.replicate n `eq` (unpackS . TL.replicate n)
313+tl_replicate n = L.replicate n `eq` (unpackS . TL.replicate (fromIntegral n))
312314
313315unf :: Int -> Char -> Maybe (Char, Char)
314316unf n c | fromEnum c * 100 > n = Nothing
@@ -616,7 +618,9 @@ tests = [
616618 testProperty "s_justifyLeft" s_justifyLeft,
617619 testProperty "sf_justifyLeft" sf_justifyLeft,
618620 testProperty "t_justifyLeft" t_justifyLeft,
619− testProperty "t_justifyRight" t_justifyRight
621+ testProperty "tl_justifyLeft" tl_justifyLeft,
622+ testProperty "t_justifyRight" t_justifyRight,
623+ testProperty "tl_justifyRight" tl_justifyRight
620624 ]
621625 ],
622626