on master help sign in
Implement findIndices.

--HG-- extra : convert_revision : 1859be7307cbd3079168f80e15162a1e6b6ffd6e

commit6e5bf43fbbb4ecd599e5af9095b8fe0fe8e54bb1 authorBryan O'Sullivan <bos@serpentine.com> dateThu 12 Feb 2009, 09:07 (18 years ago) parentb216a25
3 files changed+29−9
Data/Text.hs+13−5 Data/Text/Fusion.hs+14−4 tests/Properties.hs+2
Data/Text.hs+13−5
@@ -130,7 +130,7 @@ module Data.Text
130130 -- * Indexing
131131 , index
132132 , findIndex
133− -- , findIndices
133+ , findIndices
134134 , elemIndex
135135 -- , elemIndices
136136 -- , count
@@ -823,16 +823,24 @@ index :: Text -> Int -> Char
823823index t n = S.index (stream t) n
824824{-# INLINE index #-}
825825
826−-- | The 'findIndex' function takes a predicate and a 'Text' and
827−-- returns the index of the first element in the 'Text'
828−-- satisfying the predicate.
826+-- | /O(n)/ The 'findIndex' function takes a predicate and a 'Text'
827+-- and returns the index of the first element in the 'Text' satisfying
828+-- the predicate. This function is subject to fusion.
829829findIndex :: (Char -> Bool) -> Text -> Maybe Int
830830findIndex p t = S.findIndex p (stream t)
831831{-# INLINE findIndex #-}
832832
833+-- | The 'findIndices' function extends 'findIndex', by returning the
834+-- indices of all elements satisfying the predicate, in ascending
835+-- order. This function is subject to fusion.
836+findIndices :: (Char -> Bool) -> Text -> [Int]
837+findIndices p t = S.findIndices p (stream t)
838+{-# INLINE findIndices #-}
839+
833840-- | /O(n)/ The 'elemIndex' function returns the index of the first
834841-- element in the given 'Text' which is equal to the query element, or
835−-- 'Nothing' if there is no such element.
842+-- 'Nothing' if there is no such element. This function is subject to
843+-- fusion.
836844elemIndex :: Char -> Text -> Maybe Int
837845elemIndex c t = S.elemIndex c (stream t)
838846
Data/Text/Fusion.hs+14−4
@@ -90,6 +90,7 @@ module Data.Text.Fusion
9090 , find
9191 , index
9292 , findIndex
93+ , findIndices
9394 , findIndexOrEnd
9495 , elemIndex
9596
@@ -784,14 +785,23 @@ index (Stream next s0 _len) n0
784785-- returns the index of the first element in the stream
785786-- satisfying the predicate.
786787findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
787−findIndex p (Stream next s0 _len) = loop_findIndex 0 s0
788+findIndex p s = case findIndices p s of
789+ (i:_) -> Just i
790+ _ -> Nothing
791+{-# INLINE [0] findIndex #-}
792+
793+-- | The 'findIndices' function takes a predicate and a stream and
794+-- returns all indices of the elements in the stream
795+-- satisfying the predicate.
796+findIndices :: (Char -> Bool) -> Stream Char -> [Int]
797+findIndices p (Stream next s0 _len) = loop_findIndex 0 s0
788798 where
789799 loop_findIndex !i !s = case next s of
790− Done -> Nothing
800+ Done -> []
791801 Skip s' -> loop_findIndex i s' -- hmm. not caught by QC
792− Yield x s' | p x -> Just i
802+ Yield x s' | p x -> i : loop_findIndex (i+1) s'
793803 | otherwise -> loop_findIndex (i+1) s'
794−{-# INLINE [0] findIndex #-}
804+{-# INLINE [0] findIndices #-}
795805
796806-- | The 'findIndexOrEnd' function takes a predicate and a stream and
797807-- returns the index of the first element in the stream
tests/Properties.hs+2
@@ -162,6 +162,7 @@ prop_partition p = L.partition p `eqP` (unpack2 . T.partition p)
162162prop_index x s = x < L.length s && x >= 0 ==>
163163 (L.!!) s x == T.index (pack s) x
164164prop_findIndex p = L.findIndex p `eqP` T.findIndex p
165+prop_findIndices p = L.findIndices p`eqP` T.findIndices p
165166prop_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
166167prop_zipWith c s = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
167168
@@ -264,6 +265,7 @@ tests = [
264265
265266 ("prop_index", mytest prop_index),
266267 ("prop_findIndex", mytest prop_findIndex),
268+ ("prop_findIndices", mytest prop_findIndices),
267269 ("prop_elemIndex", mytest prop_elemIndex),
268270 ("prop_zipWith", mytest prop_zipWith)
269271 ]