module Ops
( useWhen
, thenUse
, unlessUse
, thenReturn
, unlessReturn
, rightJust
, fromMaybeM
, orElseM
, flatMapM
, groupTuplesBy
, mergeBy
) where
import Control.Applicative
import qualified Data.Either.Combinators as EC
thenUse :: Alternative f => Bool -> a -> f a
False `thenUse` _ = empty
True `thenUse` a = pure a
useWhen :: Alternative f => a -> Bool -> f a
_ `useWhen` False = empty
a `useWhen` True = pure a
unlessUse :: Alternative f => Bool -> a -> f a
True `unlessUse` _ = empty
False `unlessUse` a = pure a
thenReturn :: (Applicative m, Alternative f) => Bool -> m a -> m (f a)
False `thenReturn` _ = pure empty
True `thenReturn` f = pure <$> f
unlessReturn :: (Applicative m, Alternative f) => Bool -> m a -> m (f a)
True `unlessReturn` _ = pure empty
False `unlessReturn` f = pure <$> f
rightJust :: Either a b -> Maybe b
rightJust = EC.rightToMaybe
fromMaybeM :: Monad m => m a -> Maybe a -> m a
fromMaybeM _ (Just a) = return a
fromMaybeM m Nothing = m
infixl 3 `orElseM`
orElseM :: Monad m => Maybe a -> m (Maybe a) -> m (Maybe a)
orElseM Nothing m = m
orElseM m _ = return m
flatMapM :: Monad m => (a -> m (Maybe b)) -> Maybe a -> m (Maybe b)
flatMapM justAction mVal = maybe (return Nothing) justAction mVal
groupTuplesBy :: (a -> a -> Bool) -> [(a, b)] -> [(a, [b])]
groupTuplesBy _ [] = []
groupTuplesBy p ((a,b):(span (p a . fst) -> (al, l))) = (a, b : map snd al) : groupTuplesBy p l
mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy _ [] l = l
mergeBy _ l [] = l
mergeBy p al@(a:ar) bl@(b:br) = case p a b of
LT -> a : mergeBy p ar bl
EQ -> mergeBy p al br
GT -> b : mergeBy p al br