@@ -21,15 +21,18 @@ module Colog.Core.Action
21
21
-- * Contravariant combinators
22
22
-- $contravariant
23
23
, cfilter
24
+ , cfilterM
24
25
, cmap
25
26
, (>$<)
26
27
, cmapMaybe
28
+ , cmapMaybeM
27
29
, (Colog.Core.Action. >$)
28
30
, cmapM
29
31
30
32
-- * Divisible combinators
31
33
-- $divisible
32
34
, divide
35
+ , divideM
33
36
, conquer
34
37
, (>*<)
35
38
, (>*)
@@ -39,6 +42,7 @@ module Colog.Core.Action
39
42
-- $decidable
40
43
, lose
41
44
, choose
45
+ , chooseM
42
46
, (>|<)
43
47
44
48
-- * Comonadic combinators
@@ -54,7 +58,7 @@ module Colog.Core.Action
54
58
, hoistLogAction
55
59
) where
56
60
57
- import Control.Monad (when , (>=>) )
61
+ import Control.Monad (when , (>=>) , (<=<) )
58
62
import Data.Coerce (coerce )
59
63
import Data.Foldable (fold , for_ )
60
64
import Data.List.NonEmpty (NonEmpty (.. ))
@@ -221,6 +225,26 @@ cfilter :: Applicative m => (msg -> Bool) -> LogAction m msg -> LogAction m msg
221
225
cfilter predicate (LogAction action) = LogAction $ \ a -> when (predicate a) (action a)
222
226
{-# INLINE cfilter #-}
223
227
228
+ {- | Performs the given logging action only if satisfies the monadic predicate.
229
+
230
+ Let's say you want to only to see logs that happened on weekends.
231
+
232
+ @
233
+ isWeekendM :: MessageWithTimestamp -> IO Bool
234
+ @
235
+
236
+ And use it with 'cfilterM' like this
237
+
238
+ @
239
+ logMessageAction :: 'LogAction' m MessageWithTimestamp
240
+ @
241
+
242
+ -}
243
+ cfilterM :: Monad m => (msg -> m Bool ) -> LogAction m msg -> LogAction m msg
244
+ cfilterM predicateM (LogAction action) =
245
+ LogAction $ \ a -> predicateM a >>= \ b -> when b (action a)
246
+ {-# INLINE cfilterM #-}
247
+
224
248
{- | This combinator is @contramap@ from contravariant functor. It is useful
225
249
when you have something like
226
250
@@ -278,6 +302,11 @@ cmapMaybe :: Applicative m => (a -> Maybe b) -> LogAction m b -> LogAction m a
278
302
cmapMaybe f (LogAction action) = LogAction (maybe (pure () ) action . f)
279
303
{-# INLINE cmapMaybe #-}
280
304
305
+ -- | Similar to `cmapMaybe` but for convertions that may fail inside a monadic context.
306
+ cmapMaybeM :: Monad m => (a -> m (Maybe b )) -> LogAction m b -> LogAction m a
307
+ cmapMaybeM f (LogAction action) = LogAction (maybe (pure () ) action <=< f)
308
+ {-# INLINE cmapMaybeM #-}
309
+
281
310
{- | This combinator is @>$@ from contravariant functor. Replaces all locations
282
311
in the output with the same value. The default definition is
283
312
@contramap . const@, so this is a more efficient version.
@@ -333,6 +362,7 @@ logTextAction :: 'LogAction' IO Text
333
362
logTextAction = 'cmapM' withTime myAction
334
363
@
335
364
-}
365
+
336
366
cmapM :: Monad m => (a -> m b ) -> LogAction m b -> LogAction m a
337
367
cmapM f (LogAction action) = LogAction (f >=> action)
338
368
{-# INLINE cmapM #-}
@@ -364,6 +394,11 @@ divide f (LogAction actionB) (LogAction actionC) = LogAction $ \(f -> (b, c)) ->
364
394
actionB b *> actionC c
365
395
{-# INLINE divide #-}
366
396
397
+ divideM :: (Monad m ) => (a -> m (b , c )) -> LogAction m b -> LogAction m c -> LogAction m a
398
+ divideM f (LogAction actionB) (LogAction actionC) =
399
+ LogAction $ \ (f -> mbc) -> mbc >>= (\ (b, c) -> actionB b *> actionC c)
400
+ {-# INLINE divideM #-}
401
+
367
402
{- | @conquer@ combinator from @Divisible@ type class.
368
403
369
404
Concretely, this is a 'LogAction' that does nothing:
@@ -444,6 +479,10 @@ choose :: (a -> Either b c) -> LogAction m b -> LogAction m c -> LogAction m a
444
479
choose f (LogAction actionB) (LogAction actionC) = LogAction (either actionB actionC . f)
445
480
{-# INLINE choose #-}
446
481
482
+ chooseM :: Monad m => (a -> m (Either b c )) -> LogAction m b -> LogAction m c -> LogAction m a
483
+ chooseM f (LogAction actionB) (LogAction actionC) = LogAction (either actionB actionC <=< f)
484
+ {-# INLINE chooseM #-}
485
+
447
486
{- | Operator version of @'choose' 'id'@.
448
487
449
488
>>> dontPrintInt = LogAction (const (putStrLn "Not printing Int"))
0 commit comments