on master help sign in
Implement and test strict and lazy zip
b846b5eBryan O'Sullivan
Data/Text.hs+9
@@ -137,6 +137,7 @@ module Data.Text
137 , count
137 , count
138
138
139 -- * Zipping and unzipping
139 -- * Zipping and unzipping
140+ , zip
140 , zipWith
141 , zipWith
141
142
142 -- -* Ordered text
143 -- -* Ordered text
@@ -864,6 +865,14 @@ count c t = S.count c (stream t)
864-------------------------------------------------------------------------------
865-------------------------------------------------------------------------------
865-- * Zipping
866-- * Zipping
866
867
868+-- | /O(n)/ 'zip' takes two 'Text's and returns a list of
869+-- corresponding pairs of bytes. If one input 'Text' is short,
870+-- excess elements of the longer 'Text' are discarded. This is
871+-- equivalent to a pair of 'unpack' operations.
872+zip :: Text -> Text -> [(Char,Char)]
873+zip a b = S.unstreamList $ S.zipWith (,) (stream a) (stream b)
874+{-# INLINE [0] zip #-}
875+
867-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
876-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
868-- given as the first argument, instead of a tupling function.
877-- given as the first argument, instead of a tupling function.
869zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
878zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
Data/Text/Fusion/Common.hs+1−1
@@ -700,7 +700,7 @@ findIndicesI p (Stream next s0 _len) = loop_findIndex 0 s0
700
700
701-- | zipWith generalises 'zip' by zipping with the function given as
701-- | zipWith generalises 'zip' by zipping with the function given as
702-- the first argument, instead of a tupling function.
702-- the first argument, instead of a tupling function.
703−zipWith :: (Char -> Char -> Char) -> Stream Char -> Stream Char -> Stream Char
703+zipWith :: (a -> a -> b) -> Stream a -> Stream a -> Stream b
704zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!: sb0 :!: Nothing) (min len1 len2)
704zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!: sb0 :!: Nothing) (min len1 len2)
705 where
705 where
706 {-# INLINE next #-}
706 {-# INLINE next #-}
Data/Text/Lazy.hs+11−3
@@ -141,6 +141,7 @@ module Data.Text.Lazy
141 , count
141 , count
142
142
143 -- * Zipping and unzipping
143 -- * Zipping and unzipping
144+ , zip
144 , zipWith
145 , zipWith
145
146
146 -- -* Ordered text
147 -- -* Ordered text
@@ -148,9 +149,8 @@ module Data.Text.Lazy
148 ) where
149 ) where
149
150
150import Prelude (Char, Bool(..), Int, Maybe(..), String,
151import Prelude (Char, Bool(..), Int, Maybe(..), String,
151− Eq(..), Ord(..), (++),
152− Read(..), Show(..),
152+ Eq(..), Ord(..), Read(..), Show(..),
153− (&&), (+), (-), (.),
153+ (&&), (+), (-), (.), ($), (++),
154 flip, fromIntegral, not, otherwise)
154 flip, fromIntegral, not, otherwise)
155import qualified Prelude as P
155import qualified Prelude as P
156import Data.Int (Int64)
156import Data.Int (Int64)
@@ -850,6 +850,14 @@ count :: Char -> Text -> Int64
850count c t = S.count c (stream t)
850count c t = S.count c (stream t)
851{-# INLINE count #-}
851{-# INLINE count #-}
852
852
853+-- | /O(n)/ 'zip' takes two 'Text's and returns a list of
854+-- corresponding pairs of bytes. If one input 'Text' is short,
855+-- excess elements of the longer 'Text' are discarded. This is
856+-- equivalent to a pair of 'unpack' operations.
857+zip :: Text -> Text -> [(Char,Char)]
858+zip a b = S.unstreamList $ S.zipWith (,) (stream a) (stream b)
859+{-# INLINE [0] zip #-}
860+
853-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
861-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
854-- given as the first argument, instead of a tupling function.
862-- given as the first argument, instead of a tupling function.
855zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
863zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
tests/Properties.hs+4
@@ -331,6 +331,8 @@ prop_T_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
331prop_TL_elemIndices c = (fmap fromIntegral . L.elemIndices c) `eqP` TL.elemIndices c
331prop_TL_elemIndices c = (fmap fromIntegral . L.elemIndices c) `eqP` TL.elemIndices c
332prop_T_count c = (L.length . L.elemIndices c) `eqP` T.count c
332prop_T_count c = (L.length . L.elemIndices c) `eqP` T.count c
333prop_TL_count c = (fromIntegral . L.length . L.elemIndices c) `eqP` TL.count c
333prop_TL_count c = (fromIntegral . L.length . L.elemIndices c) `eqP` TL.count c
334+prop_T_zip s = L.zip s `eqP` T.zip (packS s)
335+prop_TL_zip s = L.zip s `eqP` TL.zip (packS s)
334prop_T_zipWith c s = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
336prop_T_zipWith c s = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
335prop_TL_zipWith c s = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
337prop_TL_zipWith c s = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
336
338
@@ -539,6 +541,8 @@ tests = [
539 ("prop_TL_elemIndices", mytest prop_TL_elemIndices),
541 ("prop_TL_elemIndices", mytest prop_TL_elemIndices),
540 ("prop_T_count", mytest prop_T_count),
542 ("prop_T_count", mytest prop_T_count),
541 ("prop_TL_count", mytest prop_TL_count),
543 ("prop_TL_count", mytest prop_TL_count),
544+ ("prop_T_zip", mytest prop_T_zip),
545+ ("prop_TL_zip", mytest prop_TL_zip),
542 ("prop_T_zipWith", mytest prop_T_zipWith),
546 ("prop_T_zipWith", mytest prop_T_zipWith),
543 ("prop_TL_zipWith", mytest prop_TL_zipWith),
547 ("prop_TL_zipWith", mytest prop_TL_zipWith),
544
548