Commits

Bryan O'Sullivan  committed d77bd97

Implement and test lazy elemIndex, elemIndices, and count

  • Participants
  • Parent commits 17ec386

Comments (0)

Files changed (5)

File Data/Text/Fusion.hs

 -- element in the given stream which is equal to the query
 -- element, or 'Nothing' if there is no such element.
 elemIndex :: Char -> Stream Char -> Maybe Int
-elemIndex a s = case elemIndices a s of
-                  (i:_) -> Just i
-                  _     -> Nothing
+elemIndex = S.elemIndexI
 {-# INLINE [0] elemIndex #-}
 
 -- | /O(n)/ The 'elemIndices' function returns the index of every
 -- element in the given stream which is equal to the query element.
 elemIndices :: Char -> Stream Char -> [Int]
-elemIndices a (Stream next s0 _len) = loop 0 s0
-  where
-    loop !i !s = case next s of
-      Done                   -> []
-      Skip    s'             -> loop i s'
-      Yield x s' | a == x    -> i : loop (i+1) s'
-                 | otherwise -> loop (i+1) s'
+elemIndices = S.elemIndicesI
 {-# INLINE [0] elemIndices #-}
 
 -- | /O(n)/ The 'count' function returns the number of times the query
 -- element appears in the given stream.
 count :: Char -> Stream Char -> Int
-count a (Stream next s0 _len) = loop 0 s0
-  where
-    loop !i !s = case next s of
-      Done                   -> i
-      Skip    s'             -> loop i s'
-      Yield x s' | a == x    -> loop (i+1) s'
-                 | otherwise -> loop i s'
+count = S.countI
 {-# INLINE [0] count #-}

File Data/Text/Fusion/Common.hs

     , indexI
     , findIndexI
     , findIndicesI
+    , elemIndexI
+    , elemIndicesI
+    , countI
 
     -- * Zipping and unzipping
     , zipWith
                                        Yield b sb' -> Yield (f a b) (sa' :!: sb' :!: Nothing)
 {-# INLINE [0] zipWith #-}
 
+-- | /O(n)/ The 'elemIndexI' function returns the index of the first
+-- element in the given stream which is equal to the query
+-- element, or 'Nothing' if there is no such element.
+elemIndexI :: Integral a => Char -> Stream Char -> Maybe a
+elemIndexI a s = case elemIndicesI a s of
+                  (i:_) -> Just i
+                  _     -> Nothing
+{-# INLINE [0] elemIndexI #-}
+
+-- | /O(n)/ The 'elemIndicesI' function returns the index of every
+-- element in the given stream which is equal to the query element.
+elemIndicesI :: Integral a => Char -> Stream Char -> [a]
+elemIndicesI a (Stream next s0 _len) = loop 0 s0
+  where
+    loop !i !s = case next s of
+      Done                   -> []
+      Skip    s'             -> loop i s'
+      Yield x s' | a == x    -> i : loop (i+1) s'
+                 | otherwise -> loop (i+1) s'
+{-# INLINE [0] elemIndicesI #-}
+
+-- | /O(n)/ The 'count' function returns the number of times the query
+-- element appears in the given stream.
+countI :: Integral a => Char -> Stream Char -> a
+countI a (Stream next s0 _len) = loop 0 s0
+  where
+    loop !i !s = case next s of
+      Done                   -> i
+      Skip    s'             -> loop i s'
+      Yield x s' | a == x    -> loop (i+1) s'
+                 | otherwise -> loop i s'
+{-# INLINE [0] countI #-}
+
 streamError :: String -> String -> a
 streamError func msg = P.error $ "Data.Text.Fusion.Common." ++ func ++ ": " ++ msg
 

File Data/Text/Lazy.hs

     , index
     , findIndex
     , findIndices
-    -- , elemIndex
-    -- , elemIndices
-    -- , count
+    , elemIndex
+    , elemIndices
+    , count
 
     -- * Zipping and unzipping
     , zipWith
 findIndices p t = S.findIndices p (stream t)
 {-# INLINE findIndices #-}
 
+-- | /O(n)/ The 'elemIndex' function returns the index of the first
+-- element in the given 'Text' which is equal to the query element, or
+-- 'Nothing' if there is no such element. This function is subject to
+-- fusion.
+elemIndex :: Char -> Text -> Maybe Int64
+elemIndex c t = S.elemIndex c (stream t)
+{-# INLINE elemIndex #-}
+
+-- | /O(n)/ The 'elemIndices' function returns the index of every
+-- element in the given 'Text' which is equal to the query
+-- element. This function is subject to fusion.
+elemIndices :: Char -> Text -> [Int64]
+elemIndices c t = S.elemIndices c (stream t)
+{-# INLINE elemIndices #-}
+
+-- | /O(n)/ The 'count' function returns the number of times the query
+-- element appears in the given 'Text'. This function is subject to
+-- fusion.
+count :: Char -> Text -> Int64
+count c t = S.count c (stream t)
+{-# INLINE count #-}
+
 -- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
 -- given as the first argument, instead of a tupling function.
 zipWith :: (Char -> Char -> Char) -> Text -> Text -> Text

File Data/Text/Lazy/Fusion.hs

     , index
     , findIndex
     , findIndices
+    , elemIndex
+    , elemIndices
+    , count
     ) where
 
 import Prelude hiding (length)
 findIndices :: (Char -> Bool) -> Stream Char -> [Int64]
 findIndices = S.findIndicesI
 {-# INLINE [0] findIndices #-}
+
+-- | /O(n)/ The 'elemIndex' function returns the index of the first
+-- element in the given stream which is equal to the query
+-- element, or 'Nothing' if there is no such element.
+elemIndex :: Char -> Stream Char -> Maybe Int64
+elemIndex = S.elemIndexI
+{-# INLINE [0] elemIndex #-}
+
+-- | /O(n)/ The 'elemIndices' function returns the index of every
+-- element in the given stream which is equal to the query element.
+elemIndices :: Char -> Stream Char -> [Int64]
+elemIndices = S.elemIndicesI
+{-# INLINE [0] elemIndices #-}
+
+-- | /O(n)/ The 'count' function returns the number of times the query
+-- element appears in the given stream.
+count :: Char -> Stream Char -> Int64
+count = S.countI
+{-# INLINE [0] count #-}

File tests/Properties.hs

 prop_T_findIndices p   = L.findIndices p `eqP` T.findIndices p
 prop_TL_findIndices p  = (fmap fromIntegral . L.findIndices p) `eqP` TL.findIndices p
 prop_T_elemIndex c     = L.elemIndex c `eqP` T.elemIndex c
+prop_TL_elemIndex c    = (fmap fromIntegral . L.elemIndex c) `eqP` TL.elemIndex c
 prop_T_elemIndices c   = L.elemIndices c`eqP` T.elemIndices c
+prop_TL_elemIndices c  = (fmap fromIntegral . L.elemIndices c) `eqP` TL.elemIndices c
 prop_T_count c         = (L.length . L.elemIndices c) `eqP` T.count c
+prop_TL_count c        = (fromIntegral . L.length . L.elemIndices c) `eqP` TL.count c
 prop_T_zipWith c s     = L.zipWith c s `eqP` (unpackT . T.zipWith c (packT s))
 prop_TL_zipWith c s    = L.zipWith c s `eqP` (unpackT . TL.zipWith c (packT s))
 
   ("prop_T_findIndices", mytest prop_T_findIndices),
   ("prop_TL_findIndices", mytest prop_TL_findIndices),
   ("prop_T_elemIndex", mytest prop_T_elemIndex),
+  ("prop_TL_elemIndex", mytest prop_TL_elemIndex),
   ("prop_T_elemIndices", mytest prop_T_elemIndices),
+  ("prop_TL_elemIndices", mytest prop_TL_elemIndices),
   ("prop_T_count", mytest prop_T_count),
+  ("prop_TL_count", mytest prop_TL_count),
   ("prop_T_zipWith", mytest prop_T_zipWith),
   ("prop_TL_zipWith", mytest prop_TL_zipWith),