on master help sign in
add mapMaybe combinator in Fold
60d13daRanjeet Ranjan
benchmark/Streamly/Benchmark/Data/Fold.hs+7
@@ -159,6 +159,13 @@ o_1_space_serial_transformation value =
159 [ bgroup "serially"
159 [ bgroup "serially"
160 [ bgroup "transformation"
160 [ bgroup "transformation"
161 [ benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
161 [ benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
162+ , benchIOSink
163+ value
164+ "mapMaybe"
165+ (S.fold
166+ (IFL.mapMaybe
167+ (\x -> case x of 1 -> Just x ; _ -> Nothing)
168+ FL.drain))
162 , benchIOSink
169 , benchIOSink
163 value
170 value
164 "sequence"
171 "sequence"
src/Streamly/Internal/Data/Fold.hs+12−1
@@ -102,7 +102,7 @@ module Streamly.Internal.Data.Fold
102 -- , ldeleteBy
102 -- , ldeleteBy
103 -- , luniq
103 -- , luniq
104 , lcatMaybes
104 , lcatMaybes
105−
105+ , mapMaybe
106 {-
106 {-
107 -- ** Mapping Filters
107 -- ** Mapping Filters
108 , lmapMaybe
108 , lmapMaybe
@@ -208,6 +208,7 @@ import Control.Monad.IO.Class (MonadIO(..))
208import Data.Functor.Identity (Identity(..))
208import Data.Functor.Identity (Identity(..))
209import Data.Int (Int64)
209import Data.Int (Int64)
210import Data.Map.Strict (Map)
210import Data.Map.Strict (Map)
211+import Data.Maybe (isJust, fromJust)
211#if __GLASGOW_HASKELL__ < 804
212#if __GLASGOW_HASKELL__ < 804
212import Data.Semigroup (Semigroup((<>)))
213import Data.Semigroup (Semigroup((<>)))
213#endif
214#endif
@@ -314,6 +315,16 @@ sequence (Fold step initial extract) = Fold step initial extract'
314mapM :: Monad m => (b -> m c) -> Fold m a b -> Fold m a c
315mapM :: Monad m => (b -> m c) -> Fold m a b -> Fold m a c
315mapM f = sequence . fmap f
316mapM f = sequence . fmap f
316
317
318+-- | @(mapMaybe f fold)@ maps a 'Maybe' returning function @f@ on the input of the fold,
319+-- filter out the 'Nothing' elements, and return a values extracted from 'Just'.
320+-- >>> S.fold (FL.mapMaybe (\x -> case x of 5 -> Just x ; _ -> Nothing) FL.sum)
321+-- (S.enumerateFromTo 1 10)
322+-- 5
323+-- /Internal/
324+{-# INLINE mapMaybe #-}
325+mapMaybe :: (Monad m) => (a -> Maybe b) -> Fold m b r -> Fold m a r
326+mapMaybe f = lmap f . lfilter isJust . lmap fromJust
327+
317------------------------------------------------------------------------------
328------------------------------------------------------------------------------
318-- Transformations on fold inputs
329-- Transformations on fold inputs
319------------------------------------------------------------------------------
330------------------------------------------------------------------------------
test/Streamly/Test/Data/Fold.hs+4
@@ -96,6 +96,9 @@ safeLast (_:xs) = safeLast xs
96last :: [String] -> Expectation
96last :: [String] -> Expectation
97last ls = S.fold FL.last (S.fromList ls) `shouldReturn` safeLast ls
97last ls = S.fold FL.last (S.fromList ls) `shouldReturn` safeLast ls
98
98
99+mapMaybe :: [Int] -> Expectation
100+mapMaybe ls = S.fold (F.mapMaybe (\x -> if even x then Just x else Nothing) FL.toList)
101+ (S.fromList ls) `shouldReturn` filter even ls
99
102
100nth :: Int -> [a] -> Maybe a
103nth :: Int -> [a] -> Maybe a
101nth idx (x:xs) = if idx == 0
104nth idx (x:xs) = if idx == 0
@@ -213,3 +216,4 @@ main = hspec $
213 prop "Any" $ Main.any predicate
216 prop "Any" $ Main.any predicate
214 prop "And" Main.and
217 prop "And" Main.and
215 prop "Or" Main.or
218 prop "Or" Main.or
219+ prop "mapMaybe" mapMaybe