@@ -82,6 +82,9 @@ module Data.Text.Fusion.Common
8282 , indexI
8383 , findIndexI
8484 , findIndicesI
85+ , elemIndexI
86+ , elemIndicesI
87+ , countI
8588
8689 -- * Zipping and unzipping
8790 , zipWith
@@ -712,6 +715,39 @@ zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :!:
712715 Yield b sb' -> Yield (f a b) (sa' :!: sb' :!: Nothing)
713716{-# INLINE [0] zipWith #-}
714717
718+-- | /O(n)/ The 'elemIndexI' function returns the index of the first
719+-- element in the given stream which is equal to the query
720+-- element, or 'Nothing' if there is no such element.
721+elemIndexI :: Integral a => Char -> Stream Char -> Maybe a
722+elemIndexI a s = case elemIndicesI a s of
723+ (i:_) -> Just i
724+ _ -> Nothing
725+{-# INLINE [0] elemIndexI #-}
726+
727+-- | /O(n)/ The 'elemIndicesI' function returns the index of every
728+-- element in the given stream which is equal to the query element.
729+elemIndicesI :: Integral a => Char -> Stream Char -> [a]
730+elemIndicesI a (Stream next s0 _len) = loop 0 s0
731+ where
732+ loop !i !s = case next s of
733+ Done -> []
734+ Skip s' -> loop i s'
735+ Yield x s' | a == x -> i : loop (i+1) s'
736+ | otherwise -> loop (i+1) s'
737+{-# INLINE [0] elemIndicesI #-}
738+
739+-- | /O(n)/ The 'count' function returns the number of times the query
740+-- element appears in the given stream.
741+countI :: Integral a => Char -> Stream Char -> a
742+countI a (Stream next s0 _len) = loop 0 s0
743+ where
744+ loop !i !s = case next s of
745+ Done -> i
746+ Skip s' -> loop i s'
747+ Yield x s' | a == x -> loop (i+1) s'
748+ | otherwise -> loop i s'
749+{-# INLINE [0] countI #-}
750+
715751streamError :: String -> String -> a
716752streamError func msg = P.error $ "Data.Text.Fusion.Common." ++ func ++ ": " ++ msg
717753