primus-0.1.0.0: src/Primus/Bool.hs
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{- |
Module : Primus.Bool
Description : boolean methods
Copyright : (c) Grant Weyburne, 2022
License : BSD-3
-}
module Primus.Bool (
-- * builders
boolMaybe,
boolEither,
boolThese,
boolThese',
-- * monadic functions
boolM,
unlessMB,
whenMB,
) where
import Data.Bool
import Data.These
{- | monadic version of 'Data.Bool.bool'
predicate appears first unlike 'Data.Bool.bool'
-}
boolM :: Monad m => m Bool -> m a -> m a -> m a
boolM mb mf mt = mb >>= bool mf mt
{- | create a 'Maybe' using a predicate and a function for the success case
predicate appears first unlike 'Data.Bool.bool'
-}
boolMaybe ::
(a -> Bool) ->
(a -> b) ->
a ->
Maybe b
boolMaybe p r a
| p a = Just (r a)
| otherwise = Nothing
{- | create a 'Either' using a predicate and functions for the failure and success case
predicates appear first unlike 'Data.Bool.bool'
-}
boolEither ::
(a -> Bool) ->
(a -> e) ->
(a -> b) ->
a ->
Either e b
boolEither p l r a
| p a = Right (r a)
| otherwise = Left (l a)
{- | create a 'These' using two predicates and functions for the This case and That case
False + * == This (a -> e)
True + False == That (a -> b)
True + True == These (a -> e) (a -> b) -- "a" effectively appears twice
predicates appear first unlike 'Data.Bool.bool'
-}
boolThese ::
(a -> Bool) ->
(a -> Bool) ->
(a -> e) ->
(a -> b) ->
a ->
These e b
boolThese p q l r = boolThese' p q l r const
{- | similar to 'boolThese' but allows you to override the 'These' case
predicates appear first unlike 'Data.Bool.bool'
-}
boolThese' ::
(a -> Bool) ->
(a -> Bool) ->
(a -> e) ->
(a -> b) ->
((e, b) -> a -> (e, b)) ->
a ->
These e b
boolThese' p q l r b a =
case (p a, q a) of
(False, _) -> This (l a)
(True, False) -> That (r a)
(True, True) -> uncurry These (b (l a, r a) a)
-- | 'Control.Monad.unless' but makes the "a" parameter available to the callback
unlessMB ::
Applicative m =>
(a -> Bool) ->
a ->
(a -> m ()) ->
m ()
unlessMB p a m = bool (m a) (pure ()) (p a)
-- | 'Control.Monad.when' but makes the "a" parameter available to the callback
whenMB ::
Applicative m =>
(a -> Bool) ->
a ->
(a -> m ()) ->
m ()
whenMB p a m = bool (pure ()) (m a) (p a)