on master help sign in
Implement elemIndices

--HG-- extra : convert_revision : b878ded7d10aee35acd378e44167be72d3467838

commitdf49b20da4f977ae92f2ae380341c31412671774 authorBryan O'Sullivan <bos@serpentine.com> dateThu 12 Feb 2009, 09:13 (18 years ago) parent6e5bf43
3 files changed+27−8
Data/Text.hs+9−1 Data/Text/Fusion.hs+16−7 tests/Properties.hs+2
Data/Text.hs+9−1
@@ -132,7 +132,7 @@ module Data.Text
132132 , findIndex
133133 , findIndices
134134 , elemIndex
135− -- , elemIndices
135+ , elemIndices
136136 -- , count
137137
138138 -- * Zipping and unzipping
@@ -843,6 +843,14 @@ findIndices p t = S.findIndices p (stream t)
843843-- fusion.
844844elemIndex :: Char -> Text -> Maybe Int
845845elemIndex 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 #-}
846854
847855-------------------------------------------------------------------------------
848856-- * Zipping
Data/Text/Fusion.hs+16−7
@@ -93,6 +93,7 @@ module Data.Text.Fusion
9393 , findIndices
9494 , findIndexOrEnd
9595 , elemIndex
96+ , elemIndices
9697
9798 -- * Zipping and unzipping
9899 , zipWith
@@ -820,15 +821,23 @@ findIndexOrEnd p (Stream next s0 _len) = loop_findIndex 0 s0
820821-- element in the given stream which is equal to the query
821822-- element, or 'Nothing' if there is no such element.
822823elemIndex :: Char -> Stream Char -> Maybe Int
823−elemIndex a (Stream next s0 _len) = loop_elemIndex 0 s0
824− where
825− loop_elemIndex !i !s = case next s of
826− Done -> Nothing
827− Skip s' -> loop_elemIndex i s'
828− Yield x s' | a == x -> Just i
829− | otherwise -> loop_elemIndex (i+1) s'
824+elemIndex a s = case elemIndices a s of
825+ (i:_) -> Just i
826+ _ -> Nothing
830827{-# INLINE [0] elemIndex #-}
831828
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+
832841-------------------------------------------------------------------------------
833842-- * Zipping
834843
tests/Properties.hs+2
@@ -164,6 +164,7 @@ prop_index x s = x < L.length s && x >= 0 ==>
164164prop_findIndex p = L.findIndex p `eqP` T.findIndex p
165165prop_findIndices p = L.findIndices p`eqP` T.findIndices p
166166prop_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
167+prop_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
167168prop_zipWith c s = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
168169
169170main = run tests =<< getArgs
@@ -267,5 +268,6 @@ tests = [
267268 ("prop_findIndex", mytest prop_findIndex),
268269 ("prop_findIndices", mytest prop_findIndices),
269270 ("prop_elemIndex", mytest prop_elemIndex),
271+ ("prop_elemIndices", mytest prop_elemIndices),
270272 ("prop_zipWith", mytest prop_zipWith)
271273 ]