on master help sign in
Add Prelude#findIndices, Prelude#findIndex, Prelude#elemIndices, Prelude#elemIndex
commit52eccb97e7b50c4d0a9bd3d0899b461d96cbb14e authorVeladus <veladus@web.de> dateMon 23 Jul 2018, 17:17 (8 years ago) parente6c75f6
3 files changed+50−1
src/Streamly/Prelude.hs+29 src/Streamly/Streams/StreamK.hs+12 test/Prop.hs+9−1
src/Streamly/Prelude.hs+29
@@ -104,6 +104,13 @@ module Streamly.Prelude
104104 , sum
105105 , product
106106
107+ -- *** Indices
108+ , findIndices
109+ , findIndex
110+ , elemIndices
111+ , elemIndex
112+
113+
107114 -- ** Map and Fold
108115 , mapM_
109116
@@ -593,6 +600,28 @@ minimum m = S.minimum (toStreamS m)
593600maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
594601maximum m = S.maximum (toStreamS m)
595602
603+-- | Finds all the indices of elements satisfying the given predicate.
604+{-# INLINE findIndices #-}
605+findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
606+findIndices = K.findIndices
607+
608+-- | Gives the index of the first stream element satisfying the given
609+-- preficate.
610+{-# INLINE findIndex #-}
611+findIndex :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe Int)
612+findIndex p = head . findIndices p
613+
614+-- | Finds the index of all elements in the stream which are equal to the
615+-- given.
616+{-# INLINE elemIndices #-}
617+elemIndices :: (IsStream t, Eq a) => a -> t m a -> t m Int
618+elemIndices a = findIndices (==a)
619+
620+-- | Gives the first index of an element in the stream, which equals the given.
621+{-# INLINE elemIndex #-}
622+elemIndex :: (Monad m, Eq a) => a -> SerialT m a -> m (Maybe Int)
623+elemIndex a = findIndex (==a)
624+
596625------------------------------------------------------------------------------
597626-- Map and Fold
598627------------------------------------------------------------------------------
src/Streamly/Streams/StreamK.hs+12
@@ -89,6 +89,7 @@ module Streamly.Streams.StreamK
8989 , last
9090 , minimum
9191 , maximum
92+ , findIndices
9293
9394 -- ** Map and Fold
9495 , mapM_
@@ -674,6 +675,17 @@ maximum m = go Nothing (toStream m)
674675 else go (Just res) r
675676 in unStream m1 defState stop single yieldk
676677
678+{-# INLINE findIndices #-}
679+findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
680+findIndices p = fromStream . go 0 . toStream
681+ where
682+ go offset m1 = Stream $ \st stp sng yld ->
683+ let single a | p a = sng offset
684+ | otherwise = stp
685+ yieldk a x | p a = yld offset $ go (offset + 1) x
686+ | otherwise = unStream (go (offset + 1) x) st stp sng yld
687+ in unStream m1 (rstState st) stp single yieldk
688+
677689------------------------------------------------------------------------------
678690-- Map and Fold
679691------------------------------------------------------------------------------
test/Prop.hs+9−1
@@ -9,7 +9,8 @@ import Control.Applicative (ZipList(..))
99import Control.Concurrent (MVar, takeMVar, putMVar, newEmptyMVar)
1010import Control.Monad (replicateM, replicateM_)
1111import Data.IORef (readIORef, modifyIORef, newIORef)
12−import Data.List (sort, foldl', scanl')
12+import Data.List (sort, foldl', scanl', findIndices, findIndex, elemIndices,
13+ elemIndex)
1314import Data.Maybe (mapMaybe)
1415import GHC.Word (Word8)
1516
@@ -347,6 +348,10 @@ transformOps constr desc t eq = do
347348 prop (desc ++ " scan") $ transform (scanl' (+) 0) $ t . (S.scanl' (+) 0)
348349 prop (desc ++ " reverse") $ transform reverse $ t . S.reverse
349350
351+ prop (desc ++ " findIndices") $ transform (findIndices odd) $ t . (S.findIndices odd)
352+ prop (desc ++ " elemIndices") $ transform (elemIndices 3) $ t . (S.elemIndices 3)
353+
354+
350355concurrentOps
351356 :: IsStream t
352357 => ([Word8] -> t IO Word8)
@@ -481,6 +486,9 @@ eliminationOps constr desc t = do
481486 prop (desc ++ " maximum") $ eliminateOp constr (wrapMaybe maximum) $ S.maximum . t
482487 prop (desc ++ " minimum") $ eliminateOp constr (wrapMaybe minimum) $ S.minimum . t
483488
489+ prop (desc ++ " findIndex") $ eliminateOp constr (findIndex odd) $ (S.findIndex odd) . t
490+ prop (desc ++ " elemIndex") $ eliminateOp constr (elemIndex 3) $ (S.elemIndex 3) . t
491+
484492-- head/tail/last may depend on the order in case of parallel streams
485493-- so we test these only for serial streams.
486494serialEliminationOps