@@ -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,
@@ -570,6 +573,24 @@ dropWhile p m = fromStream $ go (toStream m)
570 | otherwise = yld a r
573 | otherwise = yld a r
571 in (S.runStream m1) ctx stp single yield
574 in (S.runStream m1) ctx stp single yield
576+-- | Map + filter: compute a stream of b from a stream of a and filter out
577+-- elements that are mapped to Nothing. It is similar to 'mapMaybe' in
578+-- 'Data.Maybe' but applies to streams instead of list.
581+{-# INLINE mapMaybe #-}
582+mapMaybe :: (IsStream t) => (a -> Maybe b) -> t m a -> t m b
583+mapMaybe f m = go (toStream m)
585+ go m1 = fromStream $ Stream $ \_ stp sng yld ->
586+ let single a = case f a of
589+ yield a r = case f a of
590+ Just b -> yld b (toStream $ go r)
591+ Nothing -> (S.runStream r) Nothing stp single yield
592+ in (S.runStream m1) Nothing stp single yield
573-- | Determine whether all elements of a stream satisfy a predicate.
594-- | Determine whether all elements of a stream satisfy a predicate.
575-- @since 0.1.0
596-- @since 0.1.0
@@ -750,6 +771,14 @@ mapM f m = go (toStream m)
750 yield a r = S.runStream (toStream (f a |: (go r))) svr stp sng yld
771 yield a r = S.runStream (toStream (f a |: (go r))) svr stp sng yld
751 in (S.runStream m1) Nothing stp single yield
772 in (S.runStream m1) Nothing stp single yield
774+-- | Monadic version mapMaybe.
777+{-# INLINE mapMaybeM #-}
778+mapMaybeM :: (IsStream t, MonadAsync m, Functor (t m))
779+ => (a -> m (Maybe b)) -> t m a -> t m b
780+mapMaybeM f = fmap fromJust . filter isJust . mapM f
753-- XXX this can utilize parallel mapping if we implement it as runStream . mapM
782-- XXX this can utilize parallel mapping if we implement it as runStream . mapM
754-- | Apply a monadic action to each element of the stream and discard the
783-- | Apply a monadic action to each element of the stream and discard the
755-- output of the action.
784-- output of the action.