on master help sign in
implement elem/notElem/all/any for StreamD
9b78a64Harendra Kumar
benchmark/Linear.hs+7−2
@@ -60,12 +60,17 @@ main = do
60 , benchIO "foldr" Ops.foldr
60 , benchIO "foldr" Ops.foldr
61 , benchIO "foldrM" Ops.foldrM
61 , benchIO "foldrM" Ops.foldrM
62 , benchIO "foldl'" Ops.foldl
62 , benchIO "foldl'" Ops.foldl
63+
63 , benchIO "last" Ops.last
64 , benchIO "last" Ops.last
64 , benchIO "length" Ops.length
65 , benchIO "length" Ops.length
65− , benchIO "sum" Ops.sum
66+ , benchIO "elem" Ops.elem
67+ , benchIO "notElem" Ops.notElem
68+ , benchIO "all" Ops.all
66− , benchIO "product" Ops.product
69+ , benchIO "any" Ops.any
67 , benchIO "maximum" Ops.maximum
70 , benchIO "maximum" Ops.maximum
68 , benchIO "minimum" Ops.minimum
71 , benchIO "minimum" Ops.minimum
72+ , benchIO "sum" Ops.sum
73+ , benchIO "product" Ops.product
69 ]
74 ]
70 , bgroup "transformation"
75 , bgroup "transformation"
71 [ benchIO "scan" Ops.scan
76 [ benchIO "scan" Ops.scan
benchmark/LinearOps.hs+13−3
@@ -11,7 +11,7 @@ module LinearOps where
11
11
12import Prelude
12import Prelude
13 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
13 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
14− subtract, undefined, Maybe(..), odd)
14+ subtract, undefined, Maybe(..), odd, Bool)
15
15
16import qualified Streamly as S
16import qualified Streamly as S
17import qualified Streamly.Prelude as S
17import qualified Streamly.Prelude as S
@@ -73,6 +73,12 @@ last, minimum, maximum :: Monad m => Stream m Int -> m (Maybe Int)
73{-# INLINE product #-}
73{-# INLINE product #-}
74foldl, length, sum, product :: Monad m => Stream m Int -> m Int
74foldl, length, sum, product :: Monad m => Stream m Int -> m Int
75
75
76+{-# INLINE all #-}
77+{-# INLINE any #-}
78+{-# INLINE elem #-}
79+{-# INLINE notElem #-}
80+elem, notElem, all, any :: Monad m => Stream m Int -> m Bool
81+
76{-# INLINE toNull #-}
82{-# INLINE toNull #-}
77toNull :: Monad m => (t m Int -> S.SerialT m Int) -> t m Int -> m ()
83toNull :: Monad m => (t m Int -> S.SerialT m Int) -> t m Int -> m ()
78
84
@@ -163,11 +169,15 @@ foldr = S.foldr (:) []
163foldrM = S.foldrM (\a xs -> return (a : xs)) []
169foldrM = S.foldrM (\a xs -> return (a : xs)) []
164foldl = S.foldl' (+) 0
170foldl = S.foldl' (+) 0
165last = S.last
171last = S.last
172+elem = S.elem maxValue
173+notElem = S.notElem maxValue
166length = S.length
174length = S.length
167−sum = S.sum
175+all = S.all (<= maxValue)
168−product = S.product
176+any = S.any (> maxValue)
169maximum = S.maximum
177maximum = S.maximum
170minimum = S.minimum
178minimum = S.minimum
179+sum = S.sum
180+product = S.product
171
181
172-------------------------------------------------------------------------------
182-------------------------------------------------------------------------------
173-- Transformation
183-- Transformation
src/Streamly/Prelude.hs+39−47
@@ -497,31 +497,15 @@ foldlM' step begin m = S.foldlM' step begin $ toStreamS m
497-- Specialized folds
497-- Specialized folds
498------------------------------------------------------------------------------
498------------------------------------------------------------------------------
499
499
500−-- | Determine whether all elements of a stream satisfy a predicate.
500+-- | Determine whether the stream is empty.
501−--
502−-- @since 0.1.0
503−all :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
504−all = K.all
505−
506−-- | Determine whether any of the elements of a stream satisfy a predicate.
507−--
508−-- @since 0.1.0
509−any :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
510−any = K.any
511−
512−-- | Determine the sum of all elements of a stream of numbers
513−--
514−-- @since 0.1.0
515−{-# INLINE sum #-}
516−sum :: (Monad m, Num a) => SerialT m a -> m a
517−sum = foldl' (+) 0
518−
519−-- | Determine the product of all elements of a stream of numbers
520--
501--
521-- @since 0.1.1
502-- @since 0.1.1
522−{-# INLINE product #-}
523−product :: (Monad m, Num a) => SerialT m a -> m a
503+null :: Monad m => SerialT m a -> m Bool
524−product = foldl' (*) 1
504+null m =
505+ let stop = return True
506+ single _ = return False
507+ yieldk _ _ = return False
508+ in (K.unStream (toStream m)) Nothing stop single yieldk
525
509
526-- | Extract the first element of the stream, if any.
510-- | Extract the first element of the stream, if any.
527--
511--
@@ -550,39 +534,19 @@ tail m =
550last :: Monad m => SerialT m a -> m (Maybe a)
534last :: Monad m => SerialT m a -> m (Maybe a)
551last m = S.last $ toStreamS m
535last m = S.last $ toStreamS m
552
536
553−-- | Determine whether the stream is empty.
554−--
555−-- @since 0.1.1
556−null :: Monad m => SerialT m a -> m Bool
557−null m =
558− let stop = return True
559− single _ = return False
560− yieldk _ _ = return False
561− in (K.unStream (toStream m)) Nothing stop single yieldk
562−
563-- | Determine whether an element is present in the stream.
537-- | Determine whether an element is present in the stream.
564--
538--
565-- @since 0.1.0
539-- @since 0.1.0
540+{-# INLINE elem #-}
566elem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
541elem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
567−elem e m = go (toStream m)
542+elem e m = S.elem e (toStreamS m)
568− where
569− go m1 =
570− let stop = return False
571− single a = return (a == e)
572− yieldk a r = if a == e then return True else go r
573− in (K.unStream m1) Nothing stop single yieldk
574
543
575-- | Determine whether an element is not present in the stream.
544-- | Determine whether an element is not present in the stream.
576--
545--
577-- @since 0.1.0
546-- @since 0.1.0
547+{-# INLINE notElem #-}
578notElem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
548notElem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
579−notElem e m = go (toStream m)
549+notElem e m = S.notElem e (toStreamS m)
580− where
581− go m1 =
582− let stop = return True
583− single a = return (a /= e)
584− yieldk a r = if a == e then return False else go r
585− in (K.unStream m1) Nothing stop single yieldk
586
550
587-- | Determine the length of the stream.
551-- | Determine the length of the stream.
588--
552--
@@ -591,6 +555,34 @@ notElem e m = go (toStream m)
591length :: Monad m => SerialT m a -> m Int
555length :: Monad m => SerialT m a -> m Int
592length = foldl' (\n _ -> n + 1) 0
556length = foldl' (\n _ -> n + 1) 0
593
557
558+-- | Determine whether all elements of a stream satisfy a predicate.
559+--
560+-- @since 0.1.0
561+{-# INLINE all #-}
562+all :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
563+all p m = S.all p (toStreamS m)
564+
565+-- | Determine whether any of the elements of a stream satisfy a predicate.
566+--
567+-- @since 0.1.0
568+{-# INLINE any #-}
569+any :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
570+any p m = S.any p (toStreamS m)
571+
572+-- | Determine the sum of all elements of a stream of numbers
573+--
574+-- @since 0.1.0
575+{-# INLINE sum #-}
576+sum :: (Monad m, Num a) => SerialT m a -> m a
577+sum = foldl' (+) 0
578+
579+-- | Determine the product of all elements of a stream of numbers
580+--
581+-- @since 0.1.1
582+{-# INLINE product #-}
583+product :: (Monad m, Num a) => SerialT m a -> m a
584+product = foldl' (*) 1
585+
594-- | Determine the minimum element in a stream.
586-- | Determine the minimum element in a stream.
595--
587--
596-- @since 0.1.0
588-- @since 0.1.0
src/Streamly/Streams/StreamD.hs+58−1
@@ -75,6 +75,10 @@ module Streamly.Streams.StreamD
75 -- ** Specialized Folds
75 -- ** Specialized Folds
76 , runStream
76 , runStream
77 , last
77 , last
78+ , elem
79+ , notElem
80+ , all
81+ , any
78 , maximum
82 , maximum
79 , minimum
83 , minimum
80
84
@@ -114,7 +118,8 @@ import Data.Maybe (fromJust, isJust)
114import GHC.Types ( SPEC(..) )
118import GHC.Types ( SPEC(..) )
115import Prelude
119import Prelude
116 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
120 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
117− takeWhile, drop, dropWhile, maximum, minimum)
121+ takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
122+ notElem)
118
123
119import Streamly.SVar (MonadAsync)
124import Streamly.SVar (MonadAsync)
120import qualified Streamly.Streams.StreamK as K
125import qualified Streamly.Streams.StreamK as K
@@ -310,6 +315,58 @@ runStream (Stream step state) = go SPEC state
310last :: Monad m => Stream m a -> m (Maybe a)
315last :: Monad m => Stream m a -> m (Maybe a)
311last = foldl' (\_ y -> Just y) Nothing
316last = foldl' (\_ y -> Just y) Nothing
312
317
318+{-# INLINE_NORMAL elem #-}
319+elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
320+elem e (Stream step state) = go state
321+ where
322+ go st = do
323+ r <- step st
324+ case r of
325+ Yield x s ->
326+ if x == e
327+ then return True
328+ else go s
329+ Stop -> return False
330+
331+{-# INLINE_NORMAL notElem #-}
332+notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
333+notElem e (Stream step state) = go state
334+ where
335+ go st = do
336+ r <- step st
337+ case r of
338+ Yield x s ->
339+ if x == e
340+ then return False
341+ else go s
342+ Stop -> return True
343+
344+{-# INLINE_NORMAL all #-}
345+all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
346+all p (Stream step state) = go state
347+ where
348+ go st = do
349+ r <- step st
350+ case r of
351+ Yield x s ->
352+ if p x
353+ then go s
354+ else return False
355+ Stop -> return True
356+
357+{-# INLINE_NORMAL any #-}
358+any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
359+any p (Stream step state) = go state
360+ where
361+ go st = do
362+ r <- step st
363+ case r of
364+ Yield x s ->
365+ if p x
366+ then return True
367+ else go s
368+ Stop -> return False
369+
313{-# INLINE_NORMAL maximum #-}
370{-# INLINE_NORMAL maximum #-}
314maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
371maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
315maximum (Stream step state) = go Nothing state
372maximum (Stream step state) = go Nothing state
src/Streamly/Streams/StreamK.hs+23−1
@@ -75,6 +75,8 @@ module Streamly.Streams.StreamK
75
75
76 -- ** Specialized Folds
76 -- ** Specialized Folds
77 , runStream
77 , runStream
78+ , elem
79+ , notElem
78 , all
80 , all
79 , any
81 , any
80 , last
82 , last
@@ -129,7 +131,7 @@ import Data.Semigroup (Semigroup(..))
129import Prelude
131import Prelude
130 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
132 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
131 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
133 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
132− maximum)
134+ maximum, elem, notElem)
133import qualified Prelude
135import qualified Prelude
134
136
135import Streamly.SVar
137import Streamly.SVar
@@ -521,6 +523,26 @@ runStream m = go (toStream m)
521 yieldk _ r = go (toStream r)
523 yieldk _ r = go (toStream r)
522 in (unStream m1) Nothing stop single yieldk
524 in (unStream m1) Nothing stop single yieldk
523
525
526+{-# INLINE elem #-}
527+elem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
528+elem e m = go (toStream m)
529+ where
530+ go m1 =
531+ let stop = return False
532+ single a = return (a == e)
533+ yieldk a r = if a == e then return True else go r
534+ in (unStream m1) Nothing stop single yieldk
535+
536+{-# INLINE notElem #-}
537+notElem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
538+notElem e m = go (toStream m)
539+ where
540+ go m1 =
541+ let stop = return True
542+ single a = return (a /= e)
543+ yieldk a r = if a == e then return False else go r
544+ in (unStream m1) Nothing stop single yieldk
545+
524all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
546all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
525all p m = go (toStream m)
547all p m = go (toStream m)
526 where
548 where