on master help sign in
Add Prelude#find, Prelude#lookup
74ce247Veladus
src/Streamly/Prelude.hs+14−1
@@ -105,6 +105,8 @@ module Streamly.Prelude
105 , minimum
105 , minimum
106 , sum
106 , sum
107 , product
107 , product
108+ , lookup
109+ , find
108
110
109 -- *** Indices
111 -- *** Indices
110 , findIndices
112 , findIndices
@@ -170,7 +172,7 @@ import Prelude
170 hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
172 hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
171 foldl, map, mapM, mapM_, sequence, all, any, sum, product, elem,
173 foldl, map, mapM, mapM_, sequence, all, any, sum, product, elem,
172 notElem, maximum, minimum, head, last, tail, length, null,
174 notElem, maximum, minimum, head, last, tail, length, null,
173− reverse, iterate, init, and, or)
175+ reverse, iterate, init, and, or, lookup)
174import qualified Prelude
176import qualified Prelude
175import qualified System.IO as IO
177import qualified System.IO as IO
176
178
@@ -612,6 +614,17 @@ minimum m = S.minimum (toStreamS m)
612maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
614maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
613maximum m = S.maximum (toStreamS m)
615maximum m = S.maximum (toStreamS m)
614
616
617+-- | Looks the given key up, treating the given stream as an association list.
618+{-# INLINE lookup #-}
619+lookup :: (Monad m, Eq a) => a -> SerialT m (a, b) -> m (Maybe b)
620+lookup = K.lookup
621+
622+-- | Returns the first element of the stream satisfying the given predicate,
623+-- if any.
624+{-# INLINE find #-}
625+find :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe a)
626+find = K.find
627+
615-- | Finds all the indices of elements satisfying the given predicate.
628-- | Finds all the indices of elements satisfying the given predicate.
616{-# INLINE findIndices #-}
629{-# INLINE findIndices #-}
617findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
630findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
src/Streamly/Streams/StreamK.hs+25−1
@@ -90,6 +90,8 @@ module Streamly.Streams.StreamK
90 , minimum
90 , minimum
91 , maximum
91 , maximum
92 , findIndices
92 , findIndices
93+ , lookup
94+ , find
93
95
94 -- ** Map and Fold
96 -- ** Map and Fold
95 , mapM_
97 , mapM_
@@ -143,7 +145,7 @@ import Data.Semigroup (Semigroup(..))
143import Prelude
145import Prelude
144 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
146 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
145 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
147 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
146− maximum, elem, notElem, null, head, tail, init, zipWith)
148+ maximum, elem, notElem, null, head, tail, init, zipWith, lookup)
147import qualified Prelude
149import qualified Prelude
148
150
149import Streamly.SVar
151import Streamly.SVar
@@ -675,6 +677,28 @@ maximum m = go Nothing (toStream m)
675 else go (Just res) r
677 else go (Just res) r
676 in unStream m1 defState stop single yieldk
678 in unStream m1 defState stop single yieldk
677
679
680+{-# INLINE lookup #-}
681+lookup :: (IsStream t, Monad m, Eq a) => a -> t m (a, b) -> m (Maybe b)
682+lookup e m = go (toStream m)
683+ where
684+ go m1 =
685+ let single (a, b) | a == e = return $ Just b
686+ | otherwise = return Nothing
687+ yieldk (a, b) x | a == e = return $ Just b
688+ | otherwise = go x
689+ in unStream m1 defState (return Nothing) single yieldk
690+
691+{-# INLINE find #-}
692+find :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m (Maybe a)
693+find p m = go (toStream m)
694+ where
695+ go m1 =
696+ let single a | p a = return $ Just a
697+ | otherwise = return Nothing
698+ yieldk a x | p a = return $ Just a
699+ | otherwise = go x
700+ in unStream m1 defState (return Nothing) single yieldk
701+
678{-# INLINE findIndices #-}
702{-# INLINE findIndices #-}
679findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
703findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
680findIndices p = fromStream . go 0 . toStream
704findIndices p = fromStream . go 0 . toStream
test/Prop.hs+3−1
@@ -10,7 +10,7 @@ import Control.Concurrent (MVar, takeMVar, putMVar, newEmptyMVar)
10import Control.Monad (replicateM, replicateM_)
10import Control.Monad (replicateM, replicateM_)
11import Data.IORef (readIORef, modifyIORef, newIORef)
11import Data.IORef (readIORef, modifyIORef, newIORef)
12import Data.List (sort, foldl', scanl', findIndices, findIndex, elemIndices,
12import Data.List (sort, foldl', scanl', findIndices, findIndex, elemIndices,
13− elemIndex)
13+ elemIndex, find)
14import Data.Maybe (mapMaybe)
14import Data.Maybe (mapMaybe)
15import GHC.Word (Word8)
15import GHC.Word (Word8)
16
16
@@ -489,6 +489,8 @@ eliminationOps constr desc t = do
489 prop (desc ++ " findIndex") $ eliminateOp constr (findIndex odd) $ (S.findIndex odd) . t
489 prop (desc ++ " findIndex") $ eliminateOp constr (findIndex odd) $ (S.findIndex odd) . t
490 prop (desc ++ " elemIndex") $ eliminateOp constr (elemIndex 3) $ (S.elemIndex 3) . t
490 prop (desc ++ " elemIndex") $ eliminateOp constr (elemIndex 3) $ (S.elemIndex 3) . t
491
491
492+ prop (desc ++ " find") $ eliminateOp constr (find even) $ (S.find even) . t
493+
492-- head/tail/last may depend on the order in case of parallel streams
494-- head/tail/last may depend on the order in case of parallel streams
493-- so we test these only for serial streams.
495-- so we test these only for serial streams.
494serialEliminationOps
496serialEliminationOps