on master help sign in
Fix yet another QC-exposed bug
320c5d0Bryan O'Sullivan
Data/Text/Fusion.hs+14−5
@@ -23,6 +23,7 @@ module Data.Text.Fusion
23 -- * Creation and elimination
23 -- * Creation and elimination
24 , stream
24 , stream
25 , unstream
25 , unstream
26+ , empty
26
27
27 -- * Basic interface
28 -- * Basic interface
28 , cons
29 , cons
@@ -99,9 +100,10 @@ import Data.Bits (shiftR, (.&.))
99import qualified Data.List as L
100import qualified Data.List as L
100import Data.Word (Word16)
101import Data.Word (Word16)
101import GHC.Exts (Int(..), (+#))
102import GHC.Exts (Int(..), (+#))
102−import Data.Text.Internal (Text(..), empty)
103+import Data.Text.Internal (Text(..))
103import Data.Text.UnsafeChar (unsafeChr)
104import Data.Text.UnsafeChar (unsafeChr)
104import qualified Data.Text.Array as A
105import qualified Data.Text.Array as A
106+import qualified Data.Text.Internal as I
105import qualified Data.Text.Utf16 as U16
107import qualified Data.Text.Utf16 as U16
106
108
107default(Int)
109default(Int)
@@ -134,7 +136,7 @@ stream (Text arr off len) = Stream next off len
134
136
135-- | /O(n)/ Convert a Stream Char into a Text.
137-- | /O(n)/ Convert a Stream Char into a Text.
136unstream :: Stream Char -> Text
138unstream :: Stream Char -> Text
137−unstream (Stream _next0 _s0 0) = empty
139+unstream (Stream _next0 _s0 0) = I.empty
138unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
140unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
139 where
141 where
140 a = runST (A.unsafeNew len >>= (\arr -> loop arr 0 len s0))
142 a = runST (A.unsafeNew len >>= (\arr -> loop arr 0 len s0))
@@ -163,6 +165,11 @@ unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
163{-# INLINE [0] unstream #-}
165{-# INLINE [0] unstream #-}
164{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
166{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
165
167
168+-- | The empty stream.
169+empty :: Stream Char
170+empty = Stream next 0 0
171+ where next _ = Done
172+{-# INLINE [0] empty #-}
166
173
167copy :: A.MArray s Word16 -> A.MArray s Word16 -> ST s ()
174copy :: A.MArray s Word16 -> A.MArray s Word16 -> ST s ()
168copy src dest = copy_loop 0
175copy src dest = copy_loop 0
@@ -445,7 +452,7 @@ foldr f z (Stream next s0 _len) = loop_foldr s0
445{-# INLINE [0] foldr #-}
452{-# INLINE [0] foldr #-}
446
453
447-- | foldr1 is a variant of 'foldr' that has no starting value argument,
454-- | foldr1 is a variant of 'foldr' that has no starting value argument,
448−-- and thust must be applied to non-empty streams.
455+-- and thus must be applied to non-empty streams.
449-- Subject to array fusion.
456-- Subject to array fusion.
450foldr1 :: (Char -> Char -> Char) -> Stream Char -> Char
457foldr1 :: (Char -> Char -> Char) -> Stream Char -> Char
451foldr1 f (Stream next s0 _len) = loop0_foldr1 s0
458foldr1 f (Stream next s0 _len) = loop0_foldr1 s0
@@ -478,7 +485,7 @@ concat = L.foldr append (Stream next Done 0)
478-- | Map a function over a stream that results in a stream and concatenate the
485-- | Map a function over a stream that results in a stream and concatenate the
479-- results.
486-- results.
480concatMap :: (Char -> Stream Char) -> Stream Char -> Stream Char
487concatMap :: (Char -> Stream Char) -> Stream Char -> Stream Char
481−concatMap f = foldr (append . f) (stream empty)
488+concatMap f = foldr (append . f) empty
482
489
483-- | /O(n)/ any @p @xs determines if any character in the stream
490-- | /O(n)/ any @p @xs determines if any character in the stream
484-- @xs@ satisifes the predicate @p@.
491-- @xs@ satisifes the predicate @p@.
@@ -556,7 +563,9 @@ scanl f z0 (Stream next0 s0 len) = Stream next (S1 :!: z0 :!: s0) (len+1)
556-- ** Generating and unfolding streams
563-- ** Generating and unfolding streams
557
564
558replicate :: Int -> Char -> Stream Char
565replicate :: Int -> Char -> Stream Char
559−replicate n c = Stream next 0 n
566+replicate n c
567+ | n < 0 = empty
568+ | otherwise = Stream next 0 n
560 where
569 where
561 {-# INLINE next #-}
570 {-# INLINE next #-}
562 next i | i >= n = Done
571 next i | i >= n = Done