on master help sign in
Add lmap and filter to Parsers
31b599fHarendra Kumar
core/src/Streamly/Internal/Data/Parser.hs+40−2
@@ -62,6 +62,11 @@ module Streamly.Internal.Data.Parser
62 , die
62 , die
63 , dieM
63 , dieM
64
64
65+ -- * Map on input
66+ , lmap
67+ , lmapM
68+ , filter
69+
65 -- * Element parsers
70 -- * Element parsers
66 , peek
71 , peek
67 , eof
72 , eof
@@ -202,8 +207,8 @@ module Streamly.Internal.Data.Parser
202where
207where
203
208
204import Control.Monad.Catch (MonadCatch, MonadThrow)
209import Control.Monad.Catch (MonadCatch, MonadThrow)
205−import Prelude
210+import Prelude hiding
206− hiding (any, all, take, takeWhile, sequence, concatMap, maybe, either)
211+ (any, all, take, takeWhile, sequence, concatMap, maybe, either, filter)
207
212
208import Streamly.Internal.Data.Fold.Type (Fold(..))
213import Streamly.Internal.Data.Fold.Type (Fold(..))
209import Streamly.Internal.Data.Parser.ParserK.Type (Parser)
214import Streamly.Internal.Data.Parser.ParserK.Type (Parser)
@@ -302,6 +307,39 @@ die = D.toParserK . D.die
302dieM :: MonadCatch m => m String -> Parser m a b
307dieM :: MonadCatch m => m String -> Parser m a b
303dieM = D.toParserK . D.dieM
308dieM = D.toParserK . D.dieM
304
309
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+
305-------------------------------------------------------------------------------
343-------------------------------------------------------------------------------
306-- Failing Parsers
344-- Failing Parsers
307-------------------------------------------------------------------------------
345-------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Parser/ParserD.hs+5
@@ -33,6 +33,11 @@ module Streamly.Internal.Data.Parser.ParserD
33 , die
33 , die
34 , dieM
34 , dieM
35
35
36+ -- * Map on input
37+ , lmap
38+ , lmapM
39+ , filter
40+
36 -- * Element parsers
41 -- * Element parsers
37 , peek
42 , peek
38 , eof
43 , eof
core/src/Streamly/Internal/Data/Parser/ParserD/Type.hs+34−1
@@ -194,6 +194,11 @@ module Streamly.Internal.Data.Parser.ParserD.Type
194 , alt
194 , alt
195 , concatMap
195 , concatMap
196
196
197+ -- * Input transformation
198+ , lmap
199+ , lmapM
200+ , filter
201+
197 , noErrorUnsafeSplit_
202 , noErrorUnsafeSplit_
198 , noErrorUnsafeSplitWith
203 , noErrorUnsafeSplitWith
199 , noErrorUnsafeConcatMap
204 , noErrorUnsafeConcatMap
@@ -216,7 +221,7 @@ import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
216import qualified Streamly.Internal.Data.Fold.Type as FL
221import qualified Streamly.Internal.Data.Fold.Type as FL
217import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
222import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
218
223
219−import Prelude hiding (concatMap)
224+import Prelude hiding (concatMap, filter)
220--
225--
221-- $setup
226-- $setup
222-- >>> :m
227-- >>> :m
@@ -1399,3 +1404,31 @@ instance (MonadThrow m, MonadState s m) => MonadState s (Parser m a) where
1399instance (MonadThrow m, MonadIO m) => MonadIO (Parser m a) where
1404instance (MonadThrow m, MonadIO m) => MonadIO (Parser m a) where
1400 {-# INLINE liftIO #-}
1405 {-# INLINE liftIO #-}
1401 liftIO = fromEffect . liftIO
1406 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