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

import Control.Exception qualified 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 = Exc IO -> IO a
forall a. Exc IO -> IO a
forall (m :: Type -> Type) a. MonadException m => Exc m -> m a
throwExc (Exc IO -> IO a) -> Exc IO -> IO a
forall a b. (a -> b) -> a -> b
$ e -> SomeException
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) = a -> m a
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a
fromResult (FailureResult e
e) = e -> m a
forall a. e -> m a
forall e (m :: Type -> Type) a. MonadThrow e m => e -> m a
throw e
e