on master help sign in
Add strict and lazy count functions.

--HG-- extra : convert_revision : 36cc8221d7d4e541e61a8077a73cf0f44ab7cb1f

commite2e3271b152791b682ced45730b90a7b9196e74c authorBryan O'Sullivan <bos@serpentine.com> dateSun 16 Aug 2009, 06:29 (17 years ago) parentbdb68cb
3 files changed+28−5
Data/Text.hs+3−2 Data/Text/Lazy.hs+18 tests/Properties.hs+7−3
Data/Text.hs+3−2
@@ -1107,10 +1107,11 @@ elemIndices c t = S.elemIndices c (stream t)
11071107{-# INLINE elemIndices #-}
11081108
11091109-- | /O(n*m)/ The 'count' function returns the number of times the
1110−-- query string appears in the given 'Text'.
1110+-- query string appears in the given 'Text'. An empty query string is
1111+-- invalid, and will cause an error to be raised.
11111112count :: Text -> Text -> Int
11121113count pat src0
1113− | l == 0 = length src0 + 1
1114+ | l == 0 = emptyError "count"
11141115 | l == 1 = countChar (unsafeHead pat) src0
11151116 | otherwise = go 0 src0
11161117 where
Data/Text/Lazy.hs+18
@@ -159,6 +159,7 @@ module Data.Text.Lazy
159159 , findIndices
160160 , elemIndex
161161 , elemIndices
162+ , count
162163 , countChar
163164
164165 -- * Zipping and unzipping
@@ -1114,6 +1115,23 @@ elemIndices :: Char -> Text -> [Int64]
11141115elemIndices c t = S.elemIndices c (stream t)
11151116{-# INLINE elemIndices #-}
11161117
1118+-- | /O(n*m)/ The 'count' function returns the number of times the
1119+-- query string appears in the given 'Text'. An empty query string is
1120+-- invalid, and will cause an error to be raised.
1121+count :: Text -> Text -> Int64
1122+count pat src0
1123+ | l == 0 = emptyError "count"
1124+ | l == 1 = countChar (head pat) src0
1125+ | otherwise = go 0 src0
1126+ where
1127+ l = length pat
1128+ go !n src = search src
1129+ where
1130+ search s | null s = n
1131+ | pat `isPrefixOf` s = go (n+1) (drop l s)
1132+ | otherwise = search (tail s)
1133+{-# INLINE [1] count #-}
1134+
11171135-- | /O(n)/ The 'countChar' function returns the number of times the
11181136-- query element appears in the given 'Text'. This function is subject
11191137-- to fusion.
tests/Properties.hs+7−3
@@ -478,9 +478,11 @@ tl_elemIndex c = (fmap fromIntegral . L.elemIndex c) `eqP` TL.elemIndex c
478478sf_elemIndices p c= (L.elemIndices c . L.filter p) `eqP` (S.elemIndices c . S.filter p)
479479t_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
480480tl_elemIndices c = (fmap fromIntegral . L.elemIndices c) `eqP` TL.elemIndices c
481−sf_countChar p c = (L.length . L.elemIndices c . L.filter p) `eqP` (S.countChar c . S.filter p)
482−t_countChar c = (L.length . L.elemIndices c) `eqP` T.countChar c
483−tl_countChar c = (fromIntegral . L.length . L.elemIndices c) `eqP` TL.countChar c
481+t_count t = (subtract 1 . L.length . T.split t) `eq` T.count t
482+tl_count t = (subtract 1 . L.genericLength . TL.split t) `eq` TL.count t
483+sf_countChar p c = (L.length . L.elemIndices c . L.filter p) `eqP` (S.countChar c . S.filter p)
484+t_countChar c = (L.length . L.elemIndices c) `eqP` T.countChar c
485+tl_countChar c = (fromIntegral . L.length . L.elemIndices c) `eqP` TL.countChar c
484486t_zip s = L.zip s `eqP` T.zip (packS s)
485487tl_zip s = L.zip s `eqP` TL.zip (packS s)
486488sf_zipWith p c s = (L.zipWith c (L.filter p s) . L.filter p) `eqP` (unpackS . S.zipWith c (S.filter p $ packS s) . S.filter p)
@@ -836,6 +838,8 @@ tests = [
836838 testProperty "sf_elemIndices" sf_elemIndices,
837839 testProperty "t_elemIndices" t_elemIndices,
838840 testProperty "tl_elemIndices" tl_elemIndices,
841+ testProperty "t_count" t_count,
842+ testProperty "tl_count" tl_count,
839843 testProperty "sf_countChar" sf_countChar,
840844 testProperty "t_countChar" t_countChar,
841845 testProperty "tl_countChar" tl_countChar