module Rest.Error
( module Rest.Types.Error
, mapE
, orThrow
, orThrowWith
, eitherToStatus
, domainReason
, (>|<)
) where
import Control.Applicative
import Control.Monad.Error.Class
import Control.Monad.Trans.Except
import Data.Semigroup
import Rest.Types.Error
infixl 8 `mapE`
mapE :: (Applicative m, Monad m) => (e -> e') -> ExceptT e m a -> ExceptT e' m a
mapE f = mapExceptT (either (Left . f) Right <$>)
orThrow :: MonadError e m => m (Maybe b) -> e -> m b
orThrow a e = a >>= throwError e `maybe` return
orThrowWith :: MonadError a m => m (Either e b) -> (e -> a) -> m b
orThrowWith a f = a >>= (throwError . f) `either` return
eitherToStatus :: Either a b -> Status a b
eitherToStatus (Left e) = Failure e
eitherToStatus (Right e) = Success e
domainReason :: a -> Reason a
domainReason = CustomReason . DomainReason
infixl 3 >|<
(>|<) :: (Applicative m, Monad m) => ExceptT e m a -> ExceptT e m a -> ExceptT e m a
a >|< b = mapE getLast (mapE Last a <!> mapE Last b)
where
ExceptT m <!> ExceptT n = ExceptT $ do
v <- m
case v of
Left e -> fmap (either (Left . (<>) e) Right) n
Right x -> return (Right x)