Skip to content

Commit 3cbf30a

Browse files
piq9117vrom911
authored andcommitted
Issue 125 - monadic version of functions (#149)
* added cfilterM * added cmapMaybeM, divideM, and chooseM * added documentation comments * removed example implementation.
1 parent 97a8486 commit 3cbf30a

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

co-log-core/src/Colog/Core/Action.hs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,18 @@ module Colog.Core.Action
2121
-- * Contravariant combinators
2222
-- $contravariant
2323
, cfilter
24+
, cfilterM
2425
, cmap
2526
, (>$<)
2627
, cmapMaybe
28+
, cmapMaybeM
2729
, (Colog.Core.Action.>$)
2830
, cmapM
2931

3032
-- * Divisible combinators
3133
-- $divisible
3234
, divide
35+
, divideM
3336
, conquer
3437
, (>*<)
3538
, (>*)
@@ -39,6 +42,7 @@ module Colog.Core.Action
3942
-- $decidable
4043
, lose
4144
, choose
45+
, chooseM
4246
, (>|<)
4347

4448
-- * Comonadic combinators
@@ -54,7 +58,7 @@ module Colog.Core.Action
5458
, hoistLogAction
5559
) where
5660

57-
import Control.Monad (when, (>=>))
61+
import Control.Monad (when, (>=>), (<=<))
5862
import Data.Coerce (coerce)
5963
import Data.Foldable (fold, for_)
6064
import Data.List.NonEmpty (NonEmpty (..))
@@ -221,6 +225,26 @@ cfilter :: Applicative m => (msg -> Bool) -> LogAction m msg -> LogAction m msg
221225
cfilter predicate (LogAction action) = LogAction $ \a -> when (predicate a) (action a)
222226
{-# INLINE cfilter #-}
223227

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+
224248
{- | This combinator is @contramap@ from contravariant functor. It is useful
225249
when you have something like
226250
@@ -278,6 +302,11 @@ cmapMaybe :: Applicative m => (a -> Maybe b) -> LogAction m b -> LogAction m a
278302
cmapMaybe f (LogAction action) = LogAction (maybe (pure ()) action . f)
279303
{-# INLINE cmapMaybe #-}
280304

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+
281310
{- | This combinator is @>$@ from contravariant functor. Replaces all locations
282311
in the output with the same value. The default definition is
283312
@contramap . const@, so this is a more efficient version.
@@ -333,6 +362,7 @@ logTextAction :: 'LogAction' IO Text
333362
logTextAction = 'cmapM' withTime myAction
334363
@
335364
-}
365+
336366
cmapM :: Monad m => (a -> m b) -> LogAction m b -> LogAction m a
337367
cmapM f (LogAction action) = LogAction (f >=> action)
338368
{-# INLINE cmapM #-}
@@ -364,6 +394,11 @@ divide f (LogAction actionB) (LogAction actionC) = LogAction $ \(f -> (b, c)) ->
364394
actionB b *> actionC c
365395
{-# INLINE divide #-}
366396

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+
367402
{- | @conquer@ combinator from @Divisible@ type class.
368403
369404
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
444479
choose f (LogAction actionB) (LogAction actionC) = LogAction (either actionB actionC . f)
445480
{-# INLINE choose #-}
446481

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+
447486
{- | Operator version of @'choose' 'id'@.
448487
449488
>>> dontPrintInt = LogAction (const (putStrLn "Not printing Int"))

0 commit comments

Comments
 (0)