-----------------------------------------------------------------------------
--
-- Module      :  Control.Monad.Except.Util
-- Copyright   :  (c) 2016 Brian W Bush
-- License     :  MIT
--
-- Maintainer  :  Brian W Bush <consult@brianwbush.info>
-- Stability   :  Stable
-- Portability :  Portable
--
-- | Utilities related to the <https://hackage.haskell.org/package/mtl mtl> package.
--
-----------------------------------------------------------------------------


{-# LANGUAGE Safe #-}


module Control.Monad.Except.Util (
-- * Assertions
  assert
, deny
-- * Input/Output
, tryIO
) where


import Control.Exception (IOException, try)
import Control.Monad (unless, when)
import Control.Monad.Except (MonadError, MonadIO, liftIO, throwError)
import Data.String (IsString(..))


-- | Attempt an IO action.
tryIO :: (IsString e, MonadError e m, MonadIO m) => IO a -> m a
tryIO = (>>= either (\e -> throwError . fromString $ show (e :: IOException)) return) . liftIO . try


-- | Make an assertion.
assert :: (IsString e, MonadError e m) => e -> Bool -> m ()
assert = flip unless . throwError


-- | Make a denial.
deny :: (IsString e, MonadError e m) => e -> Bool -> m ()
deny = flip when . throwError