on master help sign in
Switch to stricter Maybe type for streaming
1c007ddBryan O'Sullivan
Data/Text/Encoding/Fusion.hs+3−5
@@ -44,6 +44,7 @@ import Data.ByteString as B
44import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
44import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
45import Data.Char (ord)
45import Data.Char (ord)
46import Data.Text.Fusion (Step(..), Stream(..))
46import Data.Text.Fusion (Step(..), Stream(..))
47+import Data.Text.Fusion.Internal (M(..))
47import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
48import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
48import Data.Word (Word8, Word16, Word32)
49import Data.Word (Word8, Word16, Word32)
49import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
50import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
@@ -55,14 +56,11 @@ import qualified Data.Text.Encoding.Utf8 as U8
55import qualified Data.Text.Encoding.Utf16 as U16
56import qualified Data.Text.Encoding.Utf16 as U16
56import qualified Data.Text.Encoding.Utf32 as U32
57import qualified Data.Text.Encoding.Utf32 as U32
57
58
58−-- Specialised, strict Maybe-like type.
59−data M = N
60− | J {-# UNPACK #-} !Word8
59+type M8 = M Word8
61− deriving (Eq, Ord, Show)
62
60
63-- Restreaming state.
61-- Restreaming state.
64data S s = S {-# UNPACK #-} !s
62data S s = S {-# UNPACK #-} !s
65− {-# UNPACK #-} !M {-# UNPACK #-} !M {-# UNPACK #-} !M
63+ {-# UNPACK #-} !M8 {-# UNPACK #-} !M8 {-# UNPACK #-} !M8
66
64
67streamASCII :: ByteString -> Stream Char
65streamASCII :: ByteString -> Stream Char
68streamASCII bs = Stream next 0 l
66streamASCII bs = Stream next 0 l
Data/Text/Fusion/Common.hs+41−41
@@ -138,14 +138,14 @@ cons w (Stream next0 s0 len) = Stream next (S2 :!: s0) (len+2) -- HINT maybe too
138
138
139-- | /O(n)/ Adds a character to the end of a stream.
139-- | /O(n)/ Adds a character to the end of a stream.
140snoc :: Stream Char -> Char -> Stream Char
140snoc :: Stream Char -> Char -> Stream Char
141−snoc (Stream next0 xs0 len) w = Stream next (Just xs0) (len+2) -- HINT maybe too high
141+snoc (Stream next0 xs0 len) w = Stream next (J xs0) (len+2) -- HINT maybe too high
142 where
142 where
143 {-# INLINE next #-}
143 {-# INLINE next #-}
144− next (Just xs) = case next0 xs of
144+ next (J xs) = case next0 xs of
145− Done -> Yield w Nothing
145+ Done -> Yield w N
146− Skip xs' -> Skip (Just xs')
146+ Skip xs' -> Skip (J xs')
147− Yield x xs' -> Yield x (Just xs')
147+ Yield x xs' -> Yield x (J xs')
148− next Nothing = Done
148+ next N = Done
149{-# INLINE [0] snoc #-}
149{-# INLINE [0] snoc #-}
150
150
151-- | /O(n)/ Appends one Stream to the other.
151-- | /O(n)/ Appends one Stream to the other.
@@ -221,17 +221,17 @@ tail (Stream next0 s0 len) = Stream next (False :!: s0) (len-1) -- HINT maybe to
221-- | /O(1)/ Returns all but the last character of a Stream Char, which
221-- | /O(1)/ Returns all but the last character of a Stream Char, which
222-- must be non-empty.
222-- must be non-empty.
223init :: Stream Char -> Stream Char
223init :: Stream Char -> Stream Char
224−init (Stream next0 s0 len) = Stream next (Nothing :!: s0) (len-1) -- HINT maybe too high
224+init (Stream next0 s0 len) = Stream next (N :!: s0) (len-1) -- HINT maybe too high
225 where
225 where
226 {-# INLINE next #-}
226 {-# INLINE next #-}
227− next (Nothing :!: s) = case next0 s of
227+ next (N :!: s) = case next0 s of
228− Done -> emptyError "init"
228+ Done -> emptyError "init"
229− Skip s' -> Skip (Nothing :!: s')
229+ Skip s' -> Skip (N :!: s')
230− Yield x s' -> Skip (Just x :!: s')
230+ Yield x s' -> Skip (J x :!: s')
231− next (Just x :!: s) = case next0 s of
231+ next (J x :!: s) = case next0 s of
232− Done -> Done
232+ Done -> Done
233− Skip s' -> Skip (Just x :!: s')
233+ Skip s' -> Skip (J x :!: s')
234− Yield x' s' -> Yield x (Just x' :!: s')
234+ Yield x' s' -> Yield x (J x' :!: s')
235{-# INLINE [0] init #-}
235{-# INLINE [0] init #-}
236
236
237-- | /O(1)/ Tests whether a Stream Char is empty or not.
237-- | /O(1)/ Tests whether a Stream Char is empty or not.
@@ -277,18 +277,18 @@ map f (Stream next0 s0 len) = Stream next s0 len -- HINT depends on f
277-- | /O(n)/ Take a character and place it between each of the
277-- | /O(n)/ Take a character and place it between each of the
278-- characters of a 'Stream Char'.
278-- characters of a 'Stream Char'.
279intersperse :: Char -> Stream Char -> Stream Char
279intersperse :: Char -> Stream Char -> Stream Char
280−intersperse c (Stream next0 s0 len) = Stream next (s0 :!: Nothing :!: S1) len -- HINT maybe too low
280+intersperse c (Stream next0 s0 len) = Stream next (s0 :!: N :!: S1) len -- HINT maybe too low
281 where
281 where
282 {-# INLINE next #-}
282 {-# INLINE next #-}
283− next (s :!: Nothing :!: S1) = case next0 s of
283+ next (s :!: N :!: S1) = case next0 s of
284 Done -> Done
284 Done -> Done
285− Skip s' -> Skip (s' :!: Nothing :!: S1)
285+ Skip s' -> Skip (s' :!: N :!: S1)
286− Yield x s' -> Skip (s' :!: Just x :!: S1)
286+ Yield x s' -> Skip (s' :!: J x :!: S1)
287− next (s :!: Just x :!: S1) = Yield x (s :!: Nothing :!: S2)
287+ next (s :!: J x :!: S1) = Yield x (s :!: N :!: S2)
288− next (s :!: Nothing :!: S2) = case next0 s of
288+ next (s :!: N :!: S2) = case next0 s of
289 Done -> Done
289 Done -> Done
290− Skip s' -> Skip (s' :!: Nothing :!: S2)
290+ Skip s' -> Skip (s' :!: N :!: S2)
291− Yield x s' -> Yield c (s' :!: Just x :!: S1)
291+ Yield x s' -> Yield c (s' :!: J x :!: S1)
292 next _ = internalError "intersperse"
292 next _ = internalError "intersperse"
293{-# INLINE [0] intersperse #-}
293{-# INLINE [0] intersperse #-}
294
294
@@ -550,19 +550,19 @@ take n0 (Stream next0 s0 len) = Stream next (n0 :!: s0) (min 0 (len - fromIntegr
550-- length of the stream.
550-- length of the stream.
551drop :: Integral a => a -> Stream Char -> Stream Char
551drop :: Integral a => a -> Stream Char -> Stream Char
552drop n0 (Stream next0 s0 len) =
552drop n0 (Stream next0 s0 len) =
553− Stream next (Just ((max 0 n0)) :!: s0) (len - fromIntegral n0) -- HINT maybe too high
553+ Stream next (J (max 0 n0) :!: s0) (len - fromIntegral n0) -- HINT maybe too high
554 where
554 where
555 {-# INLINE next #-}
555 {-# INLINE next #-}
556− next (Just !n :!: s)
556+ next (J n :!: s)
557− | n == 0 = Skip (Nothing :!: s)
557+ | n == 0 = Skip (N :!: s)
558 | otherwise = case next0 s of
558 | otherwise = case next0 s of
559 Done -> Done
559 Done -> Done
560− Skip s' -> Skip (Just n :!: s')
560+ Skip s' -> Skip (J n :!: s')
561− Yield _ s' -> Skip (Just (n-1) :!: s')
561+ Yield _ s' -> Skip (J (n-1) :!: s')
562− next (Nothing :!: s) = case next0 s of
562+ next (N :!: s) = case next0 s of
563 Done -> Done
563 Done -> Done
564− Skip s' -> Skip (Nothing :!: s')
564+ Skip s' -> Skip (N :!: s')
565− Yield x s' -> Yield x (Nothing :!: s')
565+ Yield x s' -> Yield x (N :!: s')
566{-# INLINE [0] drop #-}
566{-# INLINE [0] drop #-}
567
567
568-- | takeWhile, applied to a predicate @p@ and a stream, returns the
568-- | takeWhile, applied to a predicate @p@ and a stream, returns the
@@ -703,18 +703,18 @@ findIndicesI p (Stream next s0 _len) = loop_findIndex 0 s0
703-- | zipWith generalises 'zip' by zipping with the function given as
703-- | zipWith generalises 'zip' by zipping with the function given as
704-- the first argument, instead of a tupling function.
704-- the first argument, instead of a tupling function.
705zipWith :: (a -> a -> b) -> Stream a -> Stream a -> Stream b
705zipWith :: (a -> a -> b) -> Stream a -> Stream a -> Stream b
706−zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!: sb0 :!: Nothing) (min len1 len2)
706+zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!: sb0 :!: N) (min len1 len2)
707 where
707 where
708 {-# INLINE next #-}
708 {-# INLINE next #-}
709− next (sa :!: sb :!: Nothing) = case next0 sa of
709+ next (sa :!: sb :!: N) = case next0 sa of
710− Done -> Done
710+ Done -> Done
711− Skip sa' -> Skip (sa' :!: sb :!: Nothing)
711+ Skip sa' -> Skip (sa' :!: sb :!: N)
712− Yield a sa' -> Skip (sa' :!: sb :!: Just a)
712+ Yield a sa' -> Skip (sa' :!: sb :!: J a)
713−
713+
714− next (sa' :!: sb :!: Just a) = case next1 sb of
714+ next (sa' :!: sb :!: J a) = case next1 sb of
715− Done -> Done
715+ Done -> Done
716− Skip sb' -> Skip (sa' :!: sb' :!: Just a)
716+ Skip sb' -> Skip (sa' :!: sb' :!: J a)
717− Yield b sb' -> Yield (f a b) (sa' :!: sb' :!: Nothing)
717+ Yield b sb' -> Yield (f a b) (sa' :!: sb' :!: N)
718{-# INLINE [0] zipWith #-}
718{-# INLINE [0] zipWith #-}
719
719
720-- | /O(n)/ The 'elemIndexI' function returns the index of the first
720-- | /O(n)/ The 'elemIndexI' function returns the index of the first
Data/Text/Fusion/Internal.hs+7−1
@@ -15,13 +15,19 @@
15
15
16module Data.Text.Fusion.Internal
16module Data.Text.Fusion.Internal
17 (
17 (
18+ M(..)
18− PairS(..)
19+ , PairS(..)
19 , Switch(..)
20 , Switch(..)
20 , Step(..)
21 , Step(..)
21 , Stream(..)
22 , Stream(..)
22 , empty
23 , empty
23 ) where
24 ) where
24
25
26+-- | Specialised, strict Maybe-like type.
27+data M a = N
28+ | J {-# UNPACK #-} !a
29+ deriving (Eq, Ord, Show)
30+
25infixl 2 :!:
31infixl 2 :!:
26data PairS a b = !a :!: !b
32data PairS a b = !a :!: !b
27 deriving (Eq, Ord, Read, Show)
33 deriving (Eq, Ord, Read, Show)