on master help sign in
Add lmap and filter to Parsers
commit31b599f415ff90f9372b339eb52c1af9681b4eed authorHarendra Kumar <harendra@composewell.com> dateWed 4 May 2022, 14:20 (4 years ago) parent5dbf2ac
3 files changed+79−3
core/src/Streamly/Internal/Data/Parser.hs+40−2 core/src/Streamly/Internal/Data/Parser/ParserD.hs+5 core/src/Streamly/Internal/Data/Parser/ParserD/Type.hs+34−1
core/src/Streamly/Internal/Data/Parser.hs+40−2
@@ -62,6 +62,11 @@ module Streamly.Internal.Data.Parser
6262 , die
6363 , dieM
6464
65+ -- * Map on input
66+ , lmap
67+ , lmapM
68+ , filter
69+
6570 -- * Element parsers
6671 , peek
6772 , eof
@@ -202,8 +207,8 @@ module Streamly.Internal.Data.Parser
202207where
203208
204209import Control.Monad.Catch (MonadCatch, MonadThrow)
205−import Prelude
206− hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
210+import Prelude hiding
211+ (any, all, take, takeWhile, sequence, concatMap, maybe, either, filter)
207212
208213import Streamly.Internal.Data.Fold.Type (Fold(..))
209214import Streamly.Internal.Data.Parser.ParserK.Type (Parser)
@@ -302,6 +307,39 @@ die = D.toParserK . D.die
302307dieM :: MonadCatch m => m String -> Parser m a b
303308dieM = D.toParserK . D.dieM
304309
310+-------------------------------------------------------------------------------
311+-- Map on input
312+-------------------------------------------------------------------------------
313+
314+-- | @lmap f parser@ maps the function @f@ on the input of the parser.
315+--
316+-- >>> Stream.parse (Parser.lmap (\x -> x * x) (Parser.fromFold Fold.sum)) (Stream.enumerateFromTo 1 100)
317+-- 338350
318+--
319+-- > lmap = Parser.lmapM return
320+--
321+-- /Internal/
322+{-# INLINE lmap #-}
323+lmap :: MonadCatch m => (a -> b) -> Parser m b r -> Parser m a r
324+lmap f p = D.toParserK $ D.lmap f $ D.fromParserK p
325+
326+-- | @lmapM f parser@ maps the monadic function @f@ on the input of the parser.
327+--
328+-- /Internal/
329+{-# INLINE lmapM #-}
330+lmapM :: MonadCatch m => (a -> m b) -> Parser m b r -> Parser m a r
331+lmapM f p = D.toParserK $ D.lmapM f $ D.fromParserK p
332+
333+-- | Include only those elements that pass a predicate.
334+--
335+-- >>> Stream.parse (Parser.filter (> 5) (Parser.fromFold Fold.sum)) $ Stream.fromList [1..10]
336+-- 40
337+--
338+-- /Internal/
339+{-# INLINE filter #-}
340+filter :: MonadCatch m => (a -> Bool) -> Parser m a b -> Parser m a b
341+filter f p = D.toParserK $ D.filter f $ D.fromParserK p
342+
305343-------------------------------------------------------------------------------
306344-- Failing Parsers
307345-------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Parser/ParserD.hs+5
@@ -33,6 +33,11 @@ module Streamly.Internal.Data.Parser.ParserD
3333 , die
3434 , dieM
3535
36+ -- * Map on input
37+ , lmap
38+ , lmapM
39+ , filter
40+
3641 -- * Element parsers
3742 , peek
3843 , eof
core/src/Streamly/Internal/Data/Parser/ParserD/Type.hs+34−1
@@ -194,6 +194,11 @@ module Streamly.Internal.Data.Parser.ParserD.Type
194194 , alt
195195 , concatMap
196196
197+ -- * Input transformation
198+ , lmap
199+ , lmapM
200+ , filter
201+
197202 , noErrorUnsafeSplit_
198203 , noErrorUnsafeSplitWith
199204 , noErrorUnsafeConcatMap
@@ -216,7 +221,7 @@ import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
216221import qualified Streamly.Internal.Data.Fold.Type as FL
217222import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
218223
219−import Prelude hiding (concatMap)
224+import Prelude hiding (concatMap, filter)
220225--
221226-- $setup
222227-- >>> :m
@@ -1399,3 +1404,31 @@ instance (MonadThrow m, MonadState s m) => MonadState s (Parser m a) where
13991404instance (MonadThrow m, MonadIO m) => MonadIO (Parser m a) where
14001405 {-# INLINE liftIO #-}
14011406 liftIO = fromEffect . liftIO
1407+
1408+------------------------------------------------------------------------------
1409+-- Mapping on input
1410+------------------------------------------------------------------------------
1411+
1412+{-# INLINE lmap #-}
1413+lmap :: (a -> b) -> Parser m b r -> Parser m a r
1414+lmap f (Parser step begin done) = Parser step1 begin done
1415+
1416+ where
1417+
1418+ step1 x a = step x (f a)
1419+
1420+{-# INLINE lmapM #-}
1421+lmapM :: Monad m => (a -> m b) -> Parser m b r -> Parser m a r
1422+lmapM f (Parser step begin done) = Parser step1 begin done
1423+
1424+ where
1425+
1426+ step1 x a = f a >>= step x
1427+
1428+{-# INLINE filter #-}
1429+filter :: Monad m => (a -> Bool) -> Parser m a b -> Parser m a b
1430+filter f (Parser step initial extract) = Parser step1 initial extract
1431+
1432+ where
1433+
1434+ step1 x a = if f a then step x a else return $ Partial 0 x