on master help sign in
Implement elemIndices
df49b20Bryan O'Sullivan
Data/Text.hs+9−1
@@ -132,7 +132,7 @@ module Data.Text
132 , findIndex
132 , findIndex
133 , findIndices
133 , findIndices
134 , elemIndex
134 , elemIndex
135− -- , elemIndices
135+ , elemIndices
136 -- , count
136 -- , count
137
137
138 -- * Zipping and unzipping
138 -- * Zipping and unzipping
@@ -843,6 +843,14 @@ findIndices p t = S.findIndices p (stream t)
843-- fusion.
843-- fusion.
844elemIndex :: Char -> Text -> Maybe Int
844elemIndex :: Char -> Text -> Maybe Int
845elemIndex c t = S.elemIndex c (stream t)
845elemIndex c t = S.elemIndex c (stream t)
846+{-# INLINE elemIndex #-}
847+
848+-- | /O(n)/ The 'elemIndices' function returns the index of every
849+-- element in the given 'Text' which is equal to the query
850+-- element. This function is subject to fusion.
851+elemIndices :: Char -> Text -> [Int]
852+elemIndices c t = S.elemIndices c (stream t)
853+{-# INLINE elemIndices #-}
846
854
847-------------------------------------------------------------------------------
855-------------------------------------------------------------------------------
848-- * Zipping
856-- * Zipping
Data/Text/Fusion.hs+16−7
@@ -93,6 +93,7 @@ module Data.Text.Fusion
93 , findIndices
93 , findIndices
94 , findIndexOrEnd
94 , findIndexOrEnd
95 , elemIndex
95 , elemIndex
96+ , elemIndices
96
97
97 -- * Zipping and unzipping
98 -- * Zipping and unzipping
98 , zipWith
99 , zipWith
@@ -820,15 +821,23 @@ findIndexOrEnd p (Stream next s0 _len) = loop_findIndex 0 s0
820-- element in the given stream which is equal to the query
821-- element in the given stream which is equal to the query
821-- element, or 'Nothing' if there is no such element.
822-- element, or 'Nothing' if there is no such element.
822elemIndex :: Char -> Stream Char -> Maybe Int
823elemIndex :: Char -> Stream Char -> Maybe Int
823−elemIndex a (Stream next s0 _len) = loop_elemIndex 0 s0
824+elemIndex a s = case elemIndices a s of
824− where
825+ (i:_) -> Just i
825− loop_elemIndex !i !s = case next s of
826− Done -> Nothing
826+ _ -> Nothing
827− Skip s' -> loop_elemIndex i s'
828− Yield x s' | a == x -> Just i
829− | otherwise -> loop_elemIndex (i+1) s'
830{-# INLINE [0] elemIndex #-}
827{-# INLINE [0] elemIndex #-}
831
828
829+-- | /O(n)/ The 'elemIndices' function returns the index of every
830+-- element in the given stream which is equal to the query element.
831+elemIndices :: Char -> Stream Char -> [Int]
832+elemIndices a (Stream next s0 _len) = loop 0 s0
833+ where
834+ loop !i !s = case next s of
835+ Done -> []
836+ Skip s' -> loop i s'
837+ Yield x s' | a == x -> i : loop (i+1) s'
838+ | otherwise -> loop (i+1) s'
839+{-# INLINE [0] elemIndices #-}
840+
832-------------------------------------------------------------------------------
841-------------------------------------------------------------------------------
833-- * Zipping
842-- * Zipping
834
843
tests/Properties.hs+2
@@ -164,6 +164,7 @@ prop_index x s = x < L.length s && x >= 0 ==>
164prop_findIndex p = L.findIndex p `eqP` T.findIndex p
164prop_findIndex p = L.findIndex p `eqP` T.findIndex p
165prop_findIndices p = L.findIndices p`eqP` T.findIndices p
165prop_findIndices p = L.findIndices p`eqP` T.findIndices p
166prop_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
166prop_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
167+prop_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
167prop_zipWith c s = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
168prop_zipWith c s = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
168
169
169main = run tests =<< getArgs
170main = run tests =<< getArgs
@@ -267,5 +268,6 @@ tests = [
267 ("prop_findIndex", mytest prop_findIndex),
268 ("prop_findIndex", mytest prop_findIndex),
268 ("prop_findIndices", mytest prop_findIndices),
269 ("prop_findIndices", mytest prop_findIndices),
269 ("prop_elemIndex", mytest prop_elemIndex),
270 ("prop_elemIndex", mytest prop_elemIndex),
271+ ("prop_elemIndices", mytest prop_elemIndices),
270 ("prop_zipWith", mytest prop_zipWith)
272 ("prop_zipWith", mytest prop_zipWith)
271 ]
273 ]