on master help sign in
Use some flatter types
commit5fd4216765248f2d8628b390d11efe4a84cbf8c9 authorBryan O'Sullivan <bos@serpentine.com> dateFri 8 May 2015, 13:33 (11 years ago) parent1e10823
3 files changed+46−32
Data/Text/Internal/Fusion.hs+7−7 Data/Text/Internal/Fusion/Common.hs+26−23 Data/Text/Internal/Fusion/Types.hs+13−2
Data/Text/Internal/Fusion.hs+7−7
@@ -166,15 +166,15 @@ reverse (Stream next s len0)
166166-- | /O(n)/ Perform the equivalent of 'scanr' over a list, only with
167167-- the input and result reversed.
168168reverseScanr :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
169−reverseScanr f z0 (Stream next0 s0 len) = Stream next (S1 :*: z0 :*: s0) (len+1) -- HINT maybe too low
169+reverseScanr f z0 (Stream next0 s0 len) = Stream next (Scan1 z0 s0) (len+1) -- HINT maybe too low
170170 where
171171 {-# INLINE next #-}
172− next (S1 :*: z :*: s) = Yield z (S2 :*: z :*: s)
173− next (S2 :*: z :*: s) = case next0 s of
174− Yield x s' -> let !x' = f x z
175− in Yield x' (S2 :*: x' :*: s')
176− Skip s' -> Skip (S2 :*: z :*: s')
177− Done -> Done
172+ next (Scan1 z s) = Yield z (Scan2 z s)
173+ next (Scan2 z s) = case next0 s of
174+ Yield x s' -> let !x' = f x z
175+ in Yield x' (Scan2 x' s')
176+ Skip s' -> Skip (Scan2 z s')
177+ Done -> Done
178178{-# INLINE reverseScanr #-}
179179
180180-- | /O(n)/ Like 'unfoldr', 'unfoldrN' builds a stream from a seed
Data/Text/Internal/Fusion/Common.hs+26−23
@@ -473,17 +473,20 @@ toTitle (Stream next0 s0 len) = Stream next (CC (False :*: s0) '\0' '\0') len
473473 next (CC s a b) = Yield a (CC s b '\0')
474474{-# INLINE [0] toTitle #-}
475475
476+data Justify i s = Just1 !i !s
477+ | Just2 !i !s
478+
476479justifyLeftI :: Integral a => a -> Char -> Stream Char -> Stream Char
477480justifyLeftI k c (Stream next0 s0 len) =
478− Stream next (s0 :*: S1 :*: 0) (larger (fromIntegral k) len)
481+ Stream next (Just1 0 s0) (larger (fromIntegral k) len)
479482 where
480− next (s :*: S1 :*: n) =
483+ next (Just1 n s) =
481484 case next0 s of
482− Done -> next (s :*: S2 :*: n)
483− Skip s' -> Skip (s' :*: S1 :*: n)
484− Yield x s' -> Yield x (s' :*: S1 :*: n+1)
485− next (s :*: S2 :*: n)
486− | n < k = Yield c (s :*: S2 :*: n+1)
485+ Done -> next (Just2 n s)
486+ Skip s' -> Skip (Just1 n s')
487+ Yield x s' -> Yield x (Just1 (n+1) s')
488+ next (Just2 n s)
489+ | n < k = Yield c (Just2 (n+1) s)
487490 | otherwise = Done
488491 {-# INLINE next #-}
489492{-# INLINE [0] justifyLeftI #-}
@@ -651,15 +654,15 @@ minimum (Stream next0 s0 _len) = loop0_minimum s0
651654-- * Building streams
652655
653656scanl :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
654−scanl f z0 (Stream next0 s0 len) = Stream next (S1 :*: z0 :*: s0) (len+1) -- HINT maybe too low
657+scanl f z0 (Stream next0 s0 len) = Stream next (Scan1 z0 s0) (len+1) -- HINT maybe too low
655658 where
656659 {-# INLINE next #-}
657− next (S1 :*: z :*: s) = Yield z (S2 :*: z :*: s)
658− next (S2 :*: z :*: s) = case next0 s of
659− Yield x s' -> let !x' = f z x
660− in Yield x' (S2 :*: x' :*: s')
661− Skip s' -> Skip (S2 :*: z :*: s')
662− Done -> Done
660+ next (Scan1 z s) = Yield z (Scan2 z s)
661+ next (Scan2 z s) = case next0 s of
662+ Yield x s' -> let !x' = f z x
663+ in Yield x' (Scan2 x' s')
664+ Skip s' -> Skip (Scan2 z s')
665+ Done -> Done
663666{-# INLINE [0] scanl #-}
664667
665668-- -----------------------------------------------------------------------------
@@ -916,17 +919,17 @@ findIndicesI p (Stream next s0 _len) = loop_findIndex 0 s0
916919-- the first argument, instead of a tupling function.
917920zipWith :: (a -> a -> b) -> Stream a -> Stream a -> Stream b
918921zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) =
919− Stream next (sa0 :*: sb0 :*: N) (smaller len1 len2)
922+ Stream next (T3 sa0 sb0 N) (smaller len1 len2)
920923 where
921− next (sa :*: sb :*: N) = case next0 sa of
922− Done -> Done
923− Skip sa' -> Skip (sa' :*: sb :*: N)
924− Yield a sa' -> Skip (sa' :*: sb :*: J a)
924+ next (T3 sa sb N) = case next0 sa of
925+ Done -> Done
926+ Skip sa' -> Skip (T3 sa' sb N)
927+ Yield a sa' -> Skip (T3 sa' sb (J a))
925928
926− next (sa' :*: sb :*: J a) = case next1 sb of
927− Done -> Done
928− Skip sb' -> Skip (sa' :*: sb' :*: J a)
929− Yield b sb' -> Yield (f a b) (sa' :*: sb' :*: N)
929+ next (T3 sa' sb (J a)) = case next1 sb of
930+ Done -> Done
931+ Skip sb' -> Skip (T3 sa' sb' (J a))
932+ Yield b sb' -> Yield (f a b) (T3 sa' sb' N)
930933{-# INLINE [0] zipWith #-}
931934
932935-- | /O(n)/ The 'countCharI' function returns the number of times the
Data/Text/Internal/Fusion/Types.hs+13−2
@@ -23,6 +23,8 @@ module Data.Text.Internal.Fusion.Types
2323 , M(..)
2424 , M8
2525 , PairS(..)
26+ , T3(..)
27+ , Scan(..)
2628 , RS(..)
2729 , Step(..)
2830 , Stream(..)
@@ -42,20 +44,29 @@ data M a = N
4244
4345type M8 = M Word8
4446
45−-- Restreaming state.
47+-- | Restreaming state.
4648data RS s
4749 = RS0 !s
4850 | RS1 !s {-# UNPACK #-} !Word8
4951 | RS2 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
5052 | RS3 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
5153
52−infixl 2 :*:
54+-- | Strict pair.
5355data PairS a b = !a :*: !b
5456 -- deriving (Eq, Ord, Show)
57+infixl 2 :*:
58+
59+-- | Strict triple.
60+data T3 a b c = T3 !a !b !c
61+
62+-- | An intermediate result in a scan.
63+data Scan s = Scan1 {-# UNPACK #-} !Char !s
64+ | Scan2 {-# UNPACK #-} !Char !s
5565
5666-- | Allow a function over a stream to switch between two states.
5767data Switch = S1 | S2
5868
69+-- | Intermediate result in a processing pipeline.
5970data Step s a = Done
6071 | Skip !s
6172 | Yield !a !s