on master help sign in
Implement and test lazy findIndex and findIndices

--HG-- extra : convert_revision : 5721d908605b1f587e56b75a57d64475df4659b5

commit90a92665d39db24e7fea5d997e88d71014624989 authorBryan O'Sullivan <bos@serpentine.com> dateSun 8 Mar 2009, 05:06 (18 years ago) parentd4acc5e
5 files changed+65−13
Data/Text/Fusion.hs+2−10 Data/Text/Fusion/Common.hs+24 Data/Text/Lazy.hs+16−2 Data/Text/Lazy/Fusion.hs+16 tests/Properties.hs+7−1
Data/Text/Fusion.hs+2−10
@@ -190,22 +190,14 @@ index = S.indexI
190190-- returns the index of the first element in the stream
191191-- satisfying the predicate.
192192findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
193−findIndex p s = case findIndices p s of
194− (i:_) -> Just i
195− _ -> Nothing
193+findIndex = S.findIndexI
196194{-# INLINE [0] findIndex #-}
197195
198196-- | The 'findIndices' function takes a predicate and a stream and
199197-- returns all indices of the elements in the stream
200198-- satisfying the predicate.
201199findIndices :: (Char -> Bool) -> Stream Char -> [Int]
202−findIndices p (Stream next s0 _len) = loop_findIndex 0 s0
203− where
204− loop_findIndex !i !s = case next s of
205− Done -> []
206− Skip s' -> loop_findIndex i s' -- hmm. not caught by QC
207− Yield x s' | p x -> i : loop_findIndex (i+1) s'
208− | otherwise -> loop_findIndex (i+1) s'
200+findIndices = S.findIndicesI
209201{-# INLINE [0] findIndices #-}
210202
211203-- | The 'findIndexOrEnd' function takes a predicate and a stream and
Data/Text/Fusion/Common.hs+24
@@ -80,6 +80,8 @@ module Data.Text.Fusion.Common
8080 -- * Indexing
8181 , find
8282 , indexI
83+ , findIndexI
84+ , findIndicesI
8385
8486 -- * Zipping and unzipping
8587 , zipWith
@@ -668,6 +670,28 @@ filter p (Stream next0 s0 len) = Stream next s0 len -- HINT maybe too high
668670 filter p (filter q s) = filter (\x -> q x && p x) s
669671 #-}
670672
673+-- | The 'findIndexI' function takes a predicate and a stream and
674+-- returns the index of the first element in the stream satisfying the
675+-- predicate.
676+findIndexI :: Integral a => (Char -> Bool) -> Stream Char -> Maybe a
677+findIndexI p s = case findIndicesI p s of
678+ (i:_) -> Just i
679+ _ -> Nothing
680+{-# INLINE [0] findIndexI #-}
681+
682+-- | The 'findIndicesI' function takes a predicate and a stream and
683+-- returns all indices of the elements in the stream satisfying the
684+-- predicate.
685+findIndicesI :: Integral a => (Char -> Bool) -> Stream Char -> [a]
686+findIndicesI p (Stream next s0 _len) = loop_findIndex 0 s0
687+ where
688+ loop_findIndex !i !s = case next s of
689+ Done -> []
690+ Skip s' -> loop_findIndex i s' -- hmm. not caught by QC
691+ Yield x s' | p x -> i : loop_findIndex (i+1) s'
692+ | otherwise -> loop_findIndex (i+1) s'
693+{-# INLINE [0] findIndicesI #-}
694+
671695-------------------------------------------------------------------------------
672696-- * Zipping
673697
Data/Text/Lazy.hs+16−2
@@ -134,8 +134,8 @@ module Data.Text.Lazy
134134
135135 -- * Indexing
136136 , index
137− -- , findIndex
138− -- , findIndices
137+ , findIndex
138+ , findIndices
139139 -- , elemIndex
140140 -- , elemIndices
141141 -- , count
@@ -814,6 +814,20 @@ index :: Text -> Int64 -> Char
814814index t n = S.index (stream t) n
815815{-# INLINE index #-}
816816
817+-- | /O(n)/ The 'findIndex' function takes a predicate and a 'Text'
818+-- and returns the index of the first element in the 'Text' satisfying
819+-- the predicate. This function is subject to fusion.
820+findIndex :: (Char -> Bool) -> Text -> Maybe Int64
821+findIndex p t = S.findIndex p (stream t)
822+{-# INLINE findIndex #-}
823+
824+-- | The 'findIndices' function extends 'findIndex', by returning the
825+-- indices of all elements satisfying the predicate, in ascending
826+-- order. This function is subject to fusion.
827+findIndices :: (Char -> Bool) -> Text -> [Int64]
828+findIndices p t = S.findIndices p (stream t)
829+{-# INLINE findIndices #-}
830+
817831-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
818832-- given as the first argument, instead of a tupling function.
819833zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text
Data/Text/Lazy/Fusion.hs+16
@@ -18,6 +18,8 @@ module Data.Text.Lazy.Fusion
1818 , length
1919 , unfoldrN
2020 , index
21+ , findIndex
22+ , findIndices
2123 ) where
2224
2325import Prelude hiding (length)
@@ -99,3 +101,17 @@ unfoldrN n = S.unfoldrNI n
99101index :: Stream Char -> Int64 -> Char
100102index = S.indexI
101103{-# INLINE [0] index #-}
104+
105+-- | The 'findIndex' function takes a predicate and a stream and
106+-- returns the index of the first element in the stream
107+-- satisfying the predicate.
108+findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int64
109+findIndex = S.findIndexI
110+{-# INLINE [0] findIndex #-}
111+
112+-- | The 'findIndices' function takes a predicate and a stream and
113+-- returns all indices of the elements in the stream
114+-- satisfying the predicate.
115+findIndices :: (Char -> Bool) -> Stream Char -> [Int64]
116+findIndices = S.findIndicesI
117+{-# INLINE [0] findIndices #-}
tests/Properties.hs+7−1
@@ -319,8 +319,12 @@ prop_TL_partition p = L.partition p `eqP` (unpack2 . TL.partition p)
319319
320320prop_T_index x s = x < L.length s && x >= 0 ==>
321321 (L.!!) s x == T.index (packT s) x
322+prop_TL_index x s = x < L.length s && x >= 0 ==>
323+ (L.!!) s x == TL.index (packT s) (fromIntegral x)
322324prop_T_findIndex p = L.findIndex p `eqP` T.findIndex p
323−prop_T_findIndices p = L.findIndices p`eqP` T.findIndices p
325+prop_TL_findIndex p = (fmap fromIntegral . L.findIndex p) `eqP` TL.findIndex p
326+prop_T_findIndices p = L.findIndices p `eqP` T.findIndices p
327+prop_TL_findIndices p = (fmap fromIntegral . L.findIndices p) `eqP` TL.findIndices p
324328prop_T_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
325329prop_T_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
326330prop_T_count c = (L.length . L.elemIndices c) `eqP` T.count c
@@ -523,7 +527,9 @@ tests = [
523527
524528 ("prop_T_index", mytest prop_T_index),
525529 ("prop_T_findIndex", mytest prop_T_findIndex),
530+ ("prop_TL_findIndex", mytest prop_TL_findIndex),
526531 ("prop_T_findIndices", mytest prop_T_findIndices),
532+ ("prop_TL_findIndices", mytest prop_TL_findIndices),
527533 ("prop_T_elemIndex", mytest prop_T_elemIndex),
528534 ("prop_T_elemIndices", mytest prop_T_elemIndices),
529535 ("prop_T_count", mytest prop_T_count),