on master help sign in
Implement and test lazy elemIndex, elemIndices, and count

--HG-- extra : convert_revision : 48dc437d2c3d639de79816544f2439091488cf24

commit90c0aaa42260799c89a928dd9d7b869b6bbda32e authorBryan O'Sullivan <bos@serpentine.com> dateSun 8 Mar 2009, 05:13 (18 years ago) parent90a9266
5 files changed+92−20
Data/Text/Fusion.hs+3−17 Data/Text/Fusion/Common.hs+36 Data/Text/Lazy.hs+25−3 Data/Text/Lazy/Fusion.hs+22 tests/Properties.hs+6
Data/Text/Fusion.hs+3−17
@@ -217,31 +217,17 @@ findIndexOrEnd p (Stream next s0 _len) = loop_findIndex 0 s0
217217-- element in the given stream which is equal to the query
218218-- element, or 'Nothing' if there is no such element.
219219elemIndex :: Char -> Stream Char -> Maybe Int
220−elemIndex a s = case elemIndices a s of
221− (i:_) -> Just i
222− _ -> Nothing
220+elemIndex = S.elemIndexI
223221{-# INLINE [0] elemIndex #-}
224222
225223-- | /O(n)/ The 'elemIndices' function returns the index of every
226224-- element in the given stream which is equal to the query element.
227225elemIndices :: Char -> Stream Char -> [Int]
228−elemIndices a (Stream next s0 _len) = loop 0 s0
229− where
230− loop !i !s = case next s of
231− Done -> []
232− Skip s' -> loop i s'
233− Yield x s' | a == x -> i : loop (i+1) s'
234− | otherwise -> loop (i+1) s'
226+elemIndices = S.elemIndicesI
235227{-# INLINE [0] elemIndices #-}
236228
237229-- | /O(n)/ The 'count' function returns the number of times the query
238230-- element appears in the given stream.
239231count :: Char -> Stream Char -> Int
240−count a (Stream next s0 _len) = loop 0 s0
241− where
242− loop !i !s = case next s of
243− Done -> i
244− Skip s' -> loop i s'
245− Yield x s' | a == x -> loop (i+1) s'
246− | otherwise -> loop i s'
232+count = S.countI
247233{-# INLINE [0] count #-}
Data/Text/Fusion/Common.hs+36
@@ -82,6 +82,9 @@ module Data.Text.Fusion.Common
8282 , indexI
8383 , findIndexI
8484 , findIndicesI
85+ , elemIndexI
86+ , elemIndicesI
87+ , countI
8588
8689 -- * Zipping and unzipping
8790 , zipWith
@@ -712,6 +715,39 @@ zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!:
712715 Yield b sb' -> Yield (f a b) (sa' :!: sb' :!: Nothing)
713716{-# INLINE [0] zipWith #-}
714717
718+-- | /O(n)/ The 'elemIndexI' function returns the index of the first
719+-- element in the given stream which is equal to the query
720+-- element, or 'Nothing' if there is no such element.
721+elemIndexI :: Integral a => Char -> Stream Char -> Maybe a
722+elemIndexI a s = case elemIndicesI a s of
723+ (i:_) -> Just i
724+ _ -> Nothing
725+{-# INLINE [0] elemIndexI #-}
726+
727+-- | /O(n)/ The 'elemIndicesI' function returns the index of every
728+-- element in the given stream which is equal to the query element.
729+elemIndicesI :: Integral a => Char -> Stream Char -> [a]
730+elemIndicesI a (Stream next s0 _len) = loop 0 s0
731+ where
732+ loop !i !s = case next s of
733+ Done -> []
734+ Skip s' -> loop i s'
735+ Yield x s' | a == x -> i : loop (i+1) s'
736+ | otherwise -> loop (i+1) s'
737+{-# INLINE [0] elemIndicesI #-}
738+
739+-- | /O(n)/ The 'count' function returns the number of times the query
740+-- element appears in the given stream.
741+countI :: Integral a => Char -> Stream Char -> a
742+countI a (Stream next s0 _len) = loop 0 s0
743+ where
744+ loop !i !s = case next s of
745+ Done -> i
746+ Skip s' -> loop i s'
747+ Yield x s' | a == x -> loop (i+1) s'
748+ | otherwise -> loop i s'
749+{-# INLINE [0] countI #-}
750+
715751streamError :: String -> String -> a
716752streamError func msg = P.error $ "Data.Text.Fusion.Common." ++ func ++ ": " ++ msg
717753
Data/Text/Lazy.hs+25−3
@@ -136,9 +136,9 @@ module Data.Text.Lazy
136136 , index
137137 , findIndex
138138 , findIndices
139− -- , elemIndex
140− -- , elemIndices
141− -- , count
139+ , elemIndex
140+ , elemIndices
141+ , count
142142
143143 -- * Zipping and unzipping
144144 , zipWith
@@ -828,6 +828,28 @@ findIndices :: (Char -> Bool) -> Text -> [Int64]
828828findIndices p t = S.findIndices p (stream t)
829829{-# INLINE findIndices #-}
830830
831+-- | /O(n)/ The 'elemIndex' function returns the index of the first
832+-- element in the given 'Text' which is equal to the query element, or
833+-- 'Nothing' if there is no such element. This function is subject to
834+-- fusion.
835+elemIndex :: Char -> Text -> Maybe Int64
836+elemIndex c t = S.elemIndex c (stream t)
837+{-# INLINE elemIndex #-}
838+
839+-- | /O(n)/ The 'elemIndices' function returns the index of every
840+-- element in the given 'Text' which is equal to the query
841+-- element. This function is subject to fusion.
842+elemIndices :: Char -> Text -> [Int64]
843+elemIndices c t = S.elemIndices c (stream t)
844+{-# INLINE elemIndices #-}
845+
846+-- | /O(n)/ The 'count' function returns the number of times the query
847+-- element appears in the given 'Text'. This function is subject to
848+-- fusion.
849+count :: Char -> Text -> Int64
850+count c t = S.count c (stream t)
851+{-# INLINE count #-}
852+
831853-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
832854-- given as the first argument, instead of a tupling function.
833855zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
Data/Text/Lazy/Fusion.hs+22
@@ -20,6 +20,9 @@ module Data.Text.Lazy.Fusion
2020 , index
2121 , findIndex
2222 , findIndices
23+ , elemIndex
24+ , elemIndices
25+ , count
2326 ) where
2427
2528import Prelude hiding (length)
@@ -115,3 +118,22 @@ findIndex = S.findIndexI
115118findIndices :: (Char -> Bool) -> Stream Char -> [Int64]
116119findIndices = S.findIndicesI
117120{-# INLINE [0] findIndices #-}
121+
122+-- | /O(n)/ The 'elemIndex' function returns the index of the first
123+-- element in the given stream which is equal to the query
124+-- element, or 'Nothing' if there is no such element.
125+elemIndex :: Char -> Stream Char -> Maybe Int64
126+elemIndex = S.elemIndexI
127+{-# INLINE [0] elemIndex #-}
128+
129+-- | /O(n)/ The 'elemIndices' function returns the index of every
130+-- element in the given stream which is equal to the query element.
131+elemIndices :: Char -> Stream Char -> [Int64]
132+elemIndices = S.elemIndicesI
133+{-# INLINE [0] elemIndices #-}
134+
135+-- | /O(n)/ The 'count' function returns the number of times the query
136+-- element appears in the given stream.
137+count :: Char -> Stream Char -> Int64
138+count = S.countI
139+{-# INLINE [0] count #-}
tests/Properties.hs+6
@@ -326,8 +326,11 @@ prop_TL_findIndex p = (fmap fromIntegral . L.findIndex p) `eqP` TL.findIndex
326326prop_T_findIndices p = L.findIndices p `eqP` T.findIndices p
327327prop_TL_findIndices p = (fmap fromIntegral . L.findIndices p) `eqP` TL.findIndices p
328328prop_T_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
329+prop_TL_elemIndex c = (fmap fromIntegral . L.elemIndex c) `eqP` TL.elemIndex c
329330prop_T_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
331+prop_TL_elemIndices c = (fmap fromIntegral . L.elemIndices c) `eqP` TL.elemIndices c
330332prop_T_count c = (L.length . L.elemIndices c) `eqP` T.count c
333+prop_TL_count c = (fromIntegral . L.length . L.elemIndices c) `eqP` TL.count c
331334prop_T_zipWith c s = L.zipWith c s `eqP` (unpackT . T.zipWith c (packT s))
332335prop_TL_zipWith c s = L.zipWith c s `eqP` (unpackT . TL.zipWith c (packT s))
333336
@@ -531,8 +534,11 @@ tests = [
531534 ("prop_T_findIndices", mytest prop_T_findIndices),
532535 ("prop_TL_findIndices", mytest prop_TL_findIndices),
533536 ("prop_T_elemIndex", mytest prop_T_elemIndex),
537+ ("prop_TL_elemIndex", mytest prop_TL_elemIndex),
534538 ("prop_T_elemIndices", mytest prop_T_elemIndices),
539+ ("prop_TL_elemIndices", mytest prop_TL_elemIndices),
535540 ("prop_T_count", mytest prop_T_count),
541+ ("prop_TL_count", mytest prop_TL_count),
536542 ("prop_T_zipWith", mytest prop_T_zipWith),
537543 ("prop_TL_zipWith", mytest prop_TL_zipWith),
538544