@@ -100,12 +100,14 @@ module Streamly.Prelude
100 , takeWhile
100 , takeWhile
102 , dropWhile
102 , dropWhile
104 -- * Reordering
105 -- * Reordering
105 , reverse
106 , reverse
107 -- * Mapping
108 -- * Mapping
109 , sequence
111 , sequence
111 -- * Zipping
113 -- * Zipping
@@ -129,6 +131,7 @@ where
129import Control.Monad (void)
131import Control.Monad (void)
130import Control.Monad.IO.Class (MonadIO(..))
132import Control.Monad.IO.Class (MonadIO(..))
131import Data.Semigroup (Semigroup(..))
133import Data.Semigroup (Semigroup(..))
134+import Data.Maybe (isJust, fromJust)
132import Prelude hiding (filter, drop, dropWhile, take,
135import Prelude hiding (filter, drop, dropWhile, take,
133 takeWhile, zipWith, foldr, foldl,
136 takeWhile, zipWith, foldr, foldl,
134 mapM, mapM_, sequence, all, any,
137 mapM, mapM_, sequence, all, any,
@@ -577,6 +580,24 @@ dropWhile p m = fromStream $ go (toStream m)
577 | otherwise = yld a r
580 | otherwise = yld a r
578 in (S.runStream m1) ctx stp single yield
581 in (S.runStream m1) ctx stp single yield
583+-- | Map + filter: compute a stream of b from a stream of a and filter out
584+-- elements that are mapped to Nothing. It is similar to 'mapMaybe' in
585+-- 'Data.Maybe' but applies to streams instead of list.
588+{-# INLINE mapMaybe #-}
589+mapMaybe :: (IsStream t) => (a -> Maybe b) -> t m a -> t m b
590+mapMaybe f m = go (toStream m)
592+ go m1 = fromStream $ Stream $ \_ stp sng yld ->
593+ let single a = case f a of
596+ yield a r = case f a of
597+ Just b -> yld b (toStream $ go r)
598+ Nothing -> (S.runStream r) Nothing stp single yield
599+ in (S.runStream m1) Nothing stp single yield
580-- | Determine whether all elements of a stream satisfy a predicate.
601-- | Determine whether all elements of a stream satisfy a predicate.
582-- @since 0.1.0
603-- @since 0.1.0
@@ -757,6 +778,14 @@ mapM f m = go (toStream m)
757 yield a r = S.runStream (toStream (f a |: (go r))) svr stp sng yld
778 yield a r = S.runStream (toStream (f a |: (go r))) svr stp sng yld
758 in (S.runStream m1) Nothing stp single yield
779 in (S.runStream m1) Nothing stp single yield
781+-- | Monadic version mapMaybe.
784+{-# INLINE mapMaybeM #-}
785+mapMaybeM :: (IsStream t, MonadAsync m, Functor (t m))
786+ => (a -> m (Maybe b)) -> t m a -> t m b
787+mapMaybeM f = fmap fromJust . filter isJust . mapM f
760-- XXX this can utilize parallel mapping if we implement it as runStream . mapM
789-- XXX this can utilize parallel mapping if we implement it as runStream . mapM
761-- | Apply a monadic action to each element of the stream and discard the
790-- | Apply a monadic action to each element of the stream and discard the
762-- output of the action.
791-- output of the action.