on master help sign in
Implement findIndices.
6e5bf43Bryan O'Sullivan
Data/Text.hs+13−5
@@ -130,7 +130,7 @@ module Data.Text
130 -- * Indexing
130 -- * Indexing
131 , index
131 , index
132 , findIndex
132 , findIndex
133− -- , findIndices
133+ , findIndices
134 , elemIndex
134 , elemIndex
135 -- , elemIndices
135 -- , elemIndices
136 -- , count
136 -- , count
@@ -823,16 +823,24 @@ index :: Text -> Int -> Char
823index t n = S.index (stream t) n
823index t n = S.index (stream t) n
824{-# INLINE index #-}
824{-# INLINE index #-}
825
825
826−-- | The 'findIndex' function takes a predicate and a 'Text' and
826+-- | /O(n)/ The 'findIndex' function takes a predicate and a 'Text'
827−-- returns the index of the first element in the 'Text'
827+-- and returns the index of the first element in the 'Text' satisfying
828−-- satisfying the predicate.
828+-- the predicate. This function is subject to fusion.
829findIndex :: (Char -> Bool) -> Text -> Maybe Int
829findIndex :: (Char -> Bool) -> Text -> Maybe Int
830findIndex p t = S.findIndex p (stream t)
830findIndex p t = S.findIndex p (stream t)
831{-# INLINE findIndex #-}
831{-# INLINE findIndex #-}
832
832
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+
833-- | /O(n)/ The 'elemIndex' function returns the index of the first
840-- | /O(n)/ The 'elemIndex' function returns the index of the first
834-- element in the given 'Text' which is equal to the query element, or
841-- 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.
836elemIndex :: Char -> Text -> Maybe Int
844elemIndex :: Char -> Text -> Maybe Int
837elemIndex c t = S.elemIndex c (stream t)
845elemIndex c t = S.elemIndex c (stream t)
838
846
Data/Text/Fusion.hs+14−4
@@ -90,6 +90,7 @@ module Data.Text.Fusion
90 , find
90 , find
91 , index
91 , index
92 , findIndex
92 , findIndex
93+ , findIndices
93 , findIndexOrEnd
94 , findIndexOrEnd
94 , elemIndex
95 , elemIndex
95
96
@@ -784,14 +785,23 @@ index (Stream next s0 _len) n0
784-- returns the index of the first element in the stream
785-- returns the index of the first element in the stream
785-- satisfying the predicate.
786-- satisfying the predicate.
786findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
787findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
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]
787−findIndex p (Stream next s0 _len) = loop_findIndex 0 s0
797+findIndices p (Stream next s0 _len) = loop_findIndex 0 s0
788 where
798 where
789 loop_findIndex !i !s = case next s of
799 loop_findIndex !i !s = case next s of
790− Done -> Nothing
800+ Done -> []
791 Skip s' -> loop_findIndex i s' -- hmm. not caught by QC
801 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'
793 | otherwise -> loop_findIndex (i+1) s'
803 | otherwise -> loop_findIndex (i+1) s'
794−{-# INLINE [0] findIndex #-}
804+{-# INLINE [0] findIndices #-}
795
805
796-- | The 'findIndexOrEnd' function takes a predicate and a stream and
806-- | The 'findIndexOrEnd' function takes a predicate and a stream and
797-- returns the index of the first element in the stream
807-- 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)
162prop_index x s = x < L.length s && x >= 0 ==>
162prop_index x s = x < L.length s && x >= 0 ==>
163 (L.!!) s x == T.index (pack s) x
163 (L.!!) s x == T.index (pack s) x
164prop_findIndex p = L.findIndex p `eqP` T.findIndex p
164prop_findIndex p = L.findIndex p `eqP` T.findIndex p
165+prop_findIndices p = L.findIndices p`eqP` T.findIndices p
165prop_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
166prop_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
166prop_zipWith c s = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
167prop_zipWith c s = L.zipWith c s `eqP` (unpack . T.zipWith c (pack s))
167
168
@@ -264,6 +265,7 @@ tests = [
264
265
265 ("prop_index", mytest prop_index),
266 ("prop_index", mytest prop_index),
266 ("prop_findIndex", mytest prop_findIndex),
267 ("prop_findIndex", mytest prop_findIndex),
268+ ("prop_findIndices", mytest prop_findIndices),
267 ("prop_elemIndex", mytest prop_elemIndex),
269 ("prop_elemIndex", mytest prop_elemIndex),
268 ("prop_zipWith", mytest prop_zipWith)
270 ("prop_zipWith", mytest prop_zipWith)
269 ]
271 ]