@@ -100,12 +100,14 @@ module Streamly.Prelude
100100 , takeWhile
101101 , drop
102102 , dropWhile
103+ , mapMaybe
103104
104105 -- * Reordering
105106 , reverse
106107
107108 -- * Mapping
108109 , mapM
110+ , mapMaybeM
109111 , sequence
110112
111113 -- * Zipping
@@ -129,6 +131,7 @@ where
129131import Control.Monad (void)
130132import Control.Monad.IO.Class (MonadIO(..))
131133import Data.Semigroup (Semigroup(..))
134+import Data.Maybe (isJust, fromJust)
132135import Prelude hiding (filter, drop, dropWhile, take,
133136 takeWhile, zipWith, foldr, foldl,
134137 mapM, mapM_, sequence, all, any,
@@ -570,6 +573,24 @@ dropWhile p m = fromStream $ go (toStream m)
570573 | otherwise = yld a r
571574 in (S.runStream m1) ctx stp single yield
572575
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.
579+--
580+-- @since 0.2.1
581+{-# INLINE mapMaybe #-}
582+mapMaybe :: (IsStream t) => (a -> Maybe b) -> t m a -> t m b
583+mapMaybe f m = go (toStream m)
584+ where
585+ go m1 = fromStream $ Stream $ \_ stp sng yld ->
586+ let single a = case f a of
587+ Just b -> sng b
588+ Nothing -> stp
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
593+
573594-- | Determine whether all elements of a stream satisfy a predicate.
574595--
575596-- @since 0.1.0
@@ -750,6 +771,14 @@ mapM f m = go (toStream m)
750771 yield a r = S.runStream (toStream (f a |: (go r))) svr stp sng yld
751772 in (S.runStream m1) Nothing stp single yield
752773
774+-- | Monadic version mapMaybe.
775+--
776+-- @since 0.2.1
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
781+
753782-- XXX this can utilize parallel mapping if we implement it as runStream . mapM
754783-- | Apply a monadic action to each element of the stream and discard the
755784-- output of the action.