module Control.Monad.Ology.General.Throw
    ( module Control.Monad.Ology.General.Throw
    , CE.Exception(..)
    , CE.ErrorCall
    , pattern CE.ErrorCall
    , CE.IOException
    ) where

import qualified Control.Exception as CE
import Control.Monad.Ology.General.Exception
import Control.Monad.Ology.Specific.Result
import Import

-- | Monads that can throw this type of exception.
class Monad m => MonadThrow e m where
    throw :: forall a. e -> m a

instance CE.Exception e => MonadThrow e IO where
    throw :: forall a. e -> IO a
throw e
e = forall (m :: Type -> Type) a. MonadException m => Exc m -> m a
throwExc forall a b. (a -> b) -> a -> b
$ forall e. Exception e => e -> SomeException
CE.toException e
e

fromResult ::
       forall m e a. MonadThrow e m
    => Result e a
    -> m a
fromResult :: forall (m :: Type -> Type) e a. MonadThrow e m => Result e a -> m a
fromResult (SuccessResult a
a) = forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a
fromResult (FailureResult e
e) = forall e (m :: Type -> Type) a. MonadThrow e m => e -> m a
throw e
e