{-# LANGUAGE DerivingVia #-}
module Control.Effect.Exceptional
  ( -- * Effects
    Exceptional
  , SafeError

    -- * Actions
  , catching
  , trying
  , throwing

  , catchSafe
  , trySafe

    -- * Interpretations
  , runExceptional

  , runExceptionalJust

  , safeErrorToError

  , runSafeError

  , safeErrorToIO

  , safeErrorToErrorIO

    -- * Simple variants of interpretations
  , runExceptionalJustSimple

  , safeErrorToIOSimple

  , safeErrorToErrorIOSimple

    -- * Threading constraints
  , ErrorThreads

    -- * MonadCatch
  , MonadCatch

    -- * Carriers
  , ExceptionallyC
  , ExceptionalC
  , SafeErrorToErrorC
  , SafeErrorC
  , SafeErrorToIOC'
  , SafeErrorToIOC
  , SafeErrorToErrorIOC'
  , SafeErrorToErrorIOC
  , SafeErrorToIOSimpleC
  , SafeErrorToErrorIOSimpleC
  ) where

import Control.Effect
import Control.Effect.Error
import Control.Effect.ErrorIO
import Control.Effect.Union

import Control.Effect.Carrier

import Control.Effect.Internal.Exceptional
import Control.Effect.Internal.Utils

-- For coercion purposes
import Control.Monad.Trans.Except
import Control.Effect.Internal.Error
import Control.Effect.Carrier.Internal.Interpret
import Control.Effect.Carrier.Internal.Intro

-- | Gain access to @eff@ and @'Catch' exc@ within a region,
-- but only if you're ready to handle any unhandled exception @e :: exc@
-- that may arise from the use of @eff@ within that region.
--
-- For example:
--
-- @
-- -- A part of the program unknowing and uncaring that the use of SomeEffect
-- -- may throw exceptions.
-- uncaringProgram :: 'Eff' SomeEffect m => m String
-- uncaringProgram = do
--   doSomeThing
--   doSomeOtherThing
--
-- caringProgram :: 'Eff' ('Exceptional' SomeEffect SomeEffectExc) m => m String
-- caringProgram =
--   'catching' \@SomeEffect uncaringProgram (\\(exc :: SomeEffectExc) -> handlerForSomeEffectExc exc)
-- @
--
-- It's possible the @'Catch' exc@ effect @'catching'@ gives you access to
-- would override another, identical @'Catch' exc@ effect that you want to use
-- inside the region. To avoid this, use 'catching' together with 'intro1':
--
-- @'catching' \@SomeEffect ('intro1' uncaringProgram) ...@
--
-- If you do this, then @'catching'@ will only introduce @eff@ to be used
-- in @uncaringProgram@, and not @'Catch' exc@.
catching :: forall eff exc m a
          . Eff (Exceptional eff exc) m
         => ExceptionallyC eff exc m a
         -> (exc -> m a)
         -> m a
catching :: ExceptionallyC eff exc m a -> (exc -> m a) -> m a
catching ExceptionallyC eff exc m a
m exc -> m a
h =
  Exceptional eff exc m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(Member e (Derivs m), Carrier m) =>
e m a -> m a
send (Exceptional eff exc m a -> m a) -> Exceptional eff exc m a -> m a
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
Union '[eff, Catch exc] m a -> Exceptional eff exc m a
forall (eff :: Effect) exc (m :: * -> *) a.
Union '[eff, Catch exc] m a -> Exceptional eff exc m a
Exceptional @eff @exc (Union '[eff, Catch exc] m a -> Exceptional eff exc m a)
-> Union '[eff, Catch exc] m a -> Exceptional eff exc m a
forall a b. (a -> b) -> a -> b
$
    ElemOf (Catch exc) '[eff, Catch exc]
-> Catch exc m a -> Union '[eff, Catch exc] m a
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union (ElemOf (Catch exc) '[Catch exc]
-> ElemOf (Catch exc) '[eff, Catch exc]
forall a (e :: a) (r :: [a]) (_e :: a).
ElemOf e r -> ElemOf e (_e : r)
There ElemOf (Catch exc) '[Catch exc]
forall a (e :: a) (r :: [a]). ElemOf e (e : r)
Here) (m a -> (exc -> m a) -> Catch exc m a
forall (m :: * -> *) a e. m a -> (e -> m a) -> Catch e m a
Catch (ExceptionallyC eff exc m a -> m a
forall (eff :: Effect) exc k (m :: k -> *) (a :: k).
ExceptionallyC eff exc m a -> m a
unExceptionallyC ExceptionallyC eff exc m a
m) exc -> m a
h)
{-# INLINE catching #-}

-- | Gain access to @'Error' exc@ within a region,
-- but only if you're ready to handle any unhandled exception @e :: exc@
-- that may arise from within that region.
catchSafe :: forall exc m a
           . Eff (SafeError exc) m
          => ExceptionallyC (Throw exc) exc m a
          -> (exc -> m a)
          -> m a
catchSafe :: ExceptionallyC (Throw exc) exc m a -> (exc -> m a) -> m a
catchSafe = ExceptionallyC (Throw exc) exc m a -> (exc -> m a) -> m a
forall (eff :: Effect) exc (m :: * -> *) a.
Eff (Exceptional eff exc) m =>
ExceptionallyC eff exc m a -> (exc -> m a) -> m a
catching
{-# INLINE catchSafe #-}

-- | Gain access to @eff@ and @'Catch' exc@ within a region.
-- If any use of @eff@ within that region 'throw's an unhandled exception
-- @e :: exc@, then this returns @Left e@.
trying :: forall eff exc m a
        . Eff (Exceptional eff exc) m
       => ExceptionallyC eff exc m a
       -> m (Either exc a)
trying :: ExceptionallyC eff exc m a -> m (Either exc a)
trying ExceptionallyC eff exc m a
m = (a -> Either exc a)
-> ExceptionallyC eff exc m a
-> ExceptionallyC eff exc m (Either exc a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either exc a
forall a b. b -> Either a b
Right ExceptionallyC eff exc m a
m ExceptionallyC eff exc m (Either exc a)
-> (exc -> m (Either exc a)) -> m (Either exc a)
forall (eff :: Effect) exc (m :: * -> *) a.
Eff (Exceptional eff exc) m =>
ExceptionallyC eff exc m a -> (exc -> m a) -> m a
`catching` (Either exc a -> m (Either exc a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either exc a -> m (Either exc a))
-> (exc -> Either exc a) -> exc -> m (Either exc a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. exc -> Either exc a
forall a b. a -> Either a b
Left)
{-# INLINE trying #-}

-- | Gain access to @'Error' exc@ within a region. If any unhandled exception
-- @e :: exc@ is 'throw'n within that region,  then this returns @Left e@.
trySafe :: forall exc m a
        . Eff (SafeError exc) m
       => ExceptionallyC (Throw exc) exc m a
       -> m (Either exc a)
trySafe :: ExceptionallyC (Throw exc) exc m a -> m (Either exc a)
trySafe = ExceptionallyC (Throw exc) exc m a -> m (Either exc a)
forall (eff :: Effect) exc (m :: * -> *) a.
Eff (Exceptional eff exc) m =>
ExceptionallyC eff exc m a -> m (Either exc a)
trying
{-# INLINE trySafe #-}

-- | Gain access to @eff@ and @'Catch' exc@ within a region,
-- rethrowing any exception @e :: exc@ that may occur from the use of
-- @eff@ within that region.
throwing :: forall eff exc m a
          . Effs [Exceptional eff exc, Throw exc] m
         => ExceptionallyC eff exc m a
         -> m a
throwing :: ExceptionallyC eff exc m a -> m a
throwing ExceptionallyC eff exc m a
m = ExceptionallyC eff exc m a
m ExceptionallyC eff exc m a -> (exc -> m a) -> m a
forall (eff :: Effect) exc (m :: * -> *) a.
Eff (Exceptional eff exc) m =>
ExceptionallyC eff exc m a -> (exc -> m a) -> m a
`catching` exc -> m a
forall e (m :: * -> *) a. Eff (Throw e) m => e -> m a
throw
{-# INLINE throwing #-}

-- | Run an @'Exceptional' eff exc@ effect if both @eff@ and @'Catch' exc@
-- are part of the effect stack.
--
-- In order for this to be safe, you must ensure that the @'Catch' exc@
-- catches all exceptions that arise from the use of @eff@ and that
-- only uses of @eff@ throws those exceptions.
-- Otherwise, the use of 'catching' is liable to catch exceptions
-- not arising from uses of @eff@, or fail to catch
-- exceptions that do arise from uses of @eff@.
runExceptional :: forall eff exc m a
                . ( Member eff (Derivs m)
                  , Eff (Catch exc) m
                  )
               => ExceptionalC eff exc m a
               -> m a
runExceptional :: ExceptionalC eff exc m a -> m a
runExceptional = ExceptionalC eff exc m a -> m a
forall h (e :: Effect) (m :: * -> *) a.
Handler h e m =>
InterpretC h e m a -> m a
interpretViaHandler
{-# INLINE runExceptional #-}

-- | Run an @'Exceptional' eff exc@ effect if @eff@ is part of the
-- effect stack, provided a function that identifies the kind of exceptions
-- that may arise from the use of @eff@.
--
-- In order for this to be safe, you must ensure that the function
-- identifies all exceptions that arise from the use of @eff@ and that
-- only uses of @eff@ throws those exceptions.
-- Otherwise, the use of 'catching' is liable to catch
-- other exceptions not arising from uses of @eff@, or fail to catch
-- exceptions that do arise from uses of @eff@.
--
-- The type of this interpreter is higher-rank, as it makes use of
-- 'InterpretReifiedC'. __This makes 'runExceptionalJust' difficult to__
-- __use partially applied; for example, you can't compose it using @'.'@.__
-- You may prefer the simpler, but less performant, 'runExceptionalJustSimple'.
runExceptionalJust :: forall eff smallExc bigExc m a
                    . ( Member eff (Derivs m)
                      , Eff (Error bigExc) m
                      )
                   => (bigExc -> Maybe smallExc)
                   -> InterpretReifiedC (Exceptional eff smallExc) m a
                   -> m a
runExceptionalJust :: (bigExc -> Maybe smallExc)
-> InterpretReifiedC (Exceptional eff smallExc) m a -> m a
runExceptionalJust bigExc -> Maybe smallExc
from = EffHandler (Exceptional eff smallExc) m
-> InterpretReifiedC (Exceptional eff smallExc) m a -> m a
forall (e :: Effect) (m :: * -> *) a.
(RepresentationalEff e, Carrier m) =>
EffHandler e m -> InterpretReifiedC e m a -> m a
interpret (EffHandler (Exceptional eff smallExc) m
 -> InterpretReifiedC (Exceptional eff smallExc) m a -> m a)
-> EffHandler (Exceptional eff smallExc) m
-> InterpretReifiedC (Exceptional eff smallExc) m a
-> m a
forall a b. (a -> b) -> a -> b
$ \(Exceptional e) -> case Union '[eff, Catch smallExc] (Effly z) x
e of
  Union ElemOf e '[eff, Catch smallExc]
Here e z x
eff       -> Algebra' (Derivs (Effly z)) (Effly z) x
forall (m :: * -> *) a. Carrier m => Algebra' (Derivs m) m a
algDerivs (ElemOf e (Derivs m) -> e z x -> Union (Derivs m) (Effly z) x
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e (Derivs m)
forall k (e :: k) (r :: [k]). Member e r => ElemOf e r
membership e z x
eff)
  Union (There ElemOf e r
pr) e z x
eff -> case Union '[Catch smallExc] (Effly z) x -> Catch smallExc (Effly z) x
forall (e :: Effect) (m :: * -> *) a.
RepresentationalEff e =>
Union '[e] m a -> e m a
extract (ElemOf e r -> e z x -> Union r (Effly z) x
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e r
pr e z x
eff) of
    Catch Effly z x
m smallExc -> Effly z x
h -> (bigExc -> Maybe smallExc)
-> Effly z x -> (smallExc -> Effly z x) -> Effly z x
forall smallExc bigExc (m :: * -> *) a.
Eff (Error bigExc) m =>
(bigExc -> Maybe smallExc) -> m a -> (smallExc -> m a) -> m a
catchJust bigExc -> Maybe smallExc
from Effly z x
m smallExc -> Effly z x
h
{-# INLINE runExceptionalJust #-}

-- | Run an @'Exceptional' eff exc@ effect if @eff@ is part of the
-- effect stack, provided a function that identifies the kind of exceptions
-- that may arise from the use of @eff@.
--
-- In order for this to be safe, you must ensure that the function
-- identifies all exceptions that arise from the use of @eff@ and that
-- only uses of @eff@ throws those exceptions.
-- Otherwise, the use of 'catching' is liable to catch
-- exceptions not arising from uses of @eff@, or fail to catch
-- exceptions that do arise from uses of @eff@.
--
-- This is a less performant version of 'runExceptionalJust', but doesn't have
-- a higher-rank type. This makes 'runExceptionalJustSimple' much easier to use
-- partially applied.
runExceptionalJustSimple :: forall eff smallExc bigExc m a p
                          . ( Member eff (Derivs m)
                            , Eff (Error bigExc) m
                            , Threaders '[ReaderThreads] m p
                            )
                         => (bigExc -> Maybe smallExc)
                         -> InterpretSimpleC (Exceptional eff smallExc) m a
                         -> m a
runExceptionalJustSimple :: (bigExc -> Maybe smallExc)
-> InterpretSimpleC (Exceptional eff smallExc) m a -> m a
runExceptionalJustSimple bigExc -> Maybe smallExc
from = EffHandler (Exceptional eff smallExc) m
-> InterpretSimpleC (Exceptional eff smallExc) m a -> m a
forall (e :: Effect) (m :: * -> *) a (p :: [Effect]).
(RepresentationalEff e, Threaders '[ReaderThreads] m p,
 Carrier m) =>
EffHandler e m -> InterpretSimpleC e m a -> m a
interpretSimple (EffHandler (Exceptional eff smallExc) m
 -> InterpretSimpleC (Exceptional eff smallExc) m a -> m a)
-> EffHandler (Exceptional eff smallExc) m
-> InterpretSimpleC (Exceptional eff smallExc) m a
-> m a
forall a b. (a -> b) -> a -> b
$ \(Exceptional e) -> case Union '[eff, Catch smallExc] (Effly z) x
e of
  Union ElemOf e '[eff, Catch smallExc]
Here e z x
eff       -> Algebra' (Derivs (Effly z)) (Effly z) x
forall (m :: * -> *) a. Carrier m => Algebra' (Derivs m) m a
algDerivs (ElemOf e (Derivs m) -> e z x -> Union (Derivs m) (Effly z) x
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e (Derivs m)
forall k (e :: k) (r :: [k]). Member e r => ElemOf e r
membership e z x
eff)
  Union (There ElemOf e r
pr) e z x
eff -> case Union '[Catch smallExc] (Effly z) x -> Catch smallExc (Effly z) x
forall (e :: Effect) (m :: * -> *) a.
RepresentationalEff e =>
Union '[e] m a -> e m a
extract (ElemOf e r -> e z x -> Union r (Effly z) x
forall (z :: * -> *) (m :: * -> *) (e :: Effect) (r :: [Effect]) a.
Coercible z m =>
ElemOf e r -> e z a -> Union r m a
Union ElemOf e r
pr e z x
eff) of
    Catch Effly z x
m smallExc -> Effly z x
h -> (bigExc -> Maybe smallExc)
-> Effly z x -> (smallExc -> Effly z x) -> Effly z x
forall smallExc bigExc (m :: * -> *) a.
Eff (Error bigExc) m =>
(bigExc -> Maybe smallExc) -> m a -> (smallExc -> m a) -> m a
catchJust bigExc -> Maybe smallExc
from Effly z x
m smallExc -> Effly z x
h
{-# INLINE runExceptionalJustSimple #-}

-- | Run a @'SafeError' exc@ effect by transforming it into an @'Error' exc@
-- effect.
safeErrorToError :: forall exc m a
                  . Eff (Error exc) m
                 => SafeErrorToErrorC exc m a
                 -> m a
safeErrorToError :: SafeErrorToErrorC exc m a -> m a
safeErrorToError = SafeErrorToErrorC exc m a -> m a
forall (eff :: Effect) exc (m :: * -> *) a.
(Member eff (Derivs m), Eff (Catch exc) m) =>
ExceptionalC eff exc m a -> m a
runExceptional
{-# INLINE safeErrorToError #-}

-- | Run a @'SafeError' e@ effect purely.
--
-- @'Derivs' ('SafeErrorC' e m) = 'SafeError' e ': 'Prims' m@
--
-- @'Prims' ('SafeErrorC' e m) = 'Control.Effect.Optional.Optional' ((->) e) ': 'Prims' m@
runSafeError :: forall e m a p
              . ( Carrier m
                , Threaders '[ErrorThreads] m p
                )
             => SafeErrorC e m a
             -> m a
runSafeError :: SafeErrorC e m a -> m a
runSafeError =
    (m (Either e a) -> (Either e a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\e
_ -> m a
forall a. a
bombPure) a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return)
  (m (Either e a) -> m a)
-> (ErrorC e m a -> m (Either e a)) -> ErrorC e m a -> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# ErrorC e m a -> m (Either e a)
forall e (m :: * -> *) a (p :: [Effect]).
(Carrier m, Threaders '[ErrorThreads] m p) =>
ErrorC e m a -> m (Either e a)
runError
  (ErrorC e m a -> m a)
-> (SafeErrorToErrorC e (ErrorC e m) a -> ErrorC e m a)
-> SafeErrorToErrorC e (ErrorC e m) a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# SafeErrorToErrorC e (ErrorC e m) a -> ErrorC e m a
forall exc (m :: * -> *) a.
Eff (Error exc) m =>
SafeErrorToErrorC exc m a -> m a
safeErrorToError
  (SafeErrorToErrorC e (ErrorC e m) a -> m a)
-> (IntroUnderC
      (SafeError e)
      '[Catch e, Throw e]
      (InterpretC ExceptionalH (SafeError e) (ErrorC e m))
      a
    -> SafeErrorToErrorC e (ErrorC e m) a)
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (InterpretC ExceptionalH (SafeError e) (ErrorC e m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderC
  (SafeError e)
  '[Catch e, Throw e]
  (InterpretC ExceptionalH (SafeError e) (ErrorC e m))
  a
-> SafeErrorToErrorC e (ErrorC e m) a
forall (new :: [Effect]) (e :: Effect) (m :: * -> *) a.
(KnownList new, IntroConsistent '[e] new m) =>
IntroUnderC e new m a -> m a
introUnder
  (IntroUnderC
   (SafeError e)
   '[Catch e, Throw e]
   (InterpretC ExceptionalH (SafeError e) (ErrorC e m))
   a
 -> m a)
-> (SafeErrorC e m a
    -> IntroUnderC
         (SafeError e)
         '[Catch e, Throw e]
         (InterpretC ExceptionalH (SafeError e) (ErrorC e m))
         a)
-> SafeErrorC e m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# SafeErrorC e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (InterpretC ExceptionalH (SafeError e) (ErrorC e m))
     a
forall exc (m :: * -> *) a.
SafeErrorC exc m a
-> IntroUnderC
     (SafeError exc)
     '[Catch exc, Throw exc]
     (SafeErrorToErrorC exc (ErrorC exc m))
     a
unSafeErrorC
{-# INLINE runSafeError #-}

bombPure :: a
bombPure :: a
bombPure = [Char] -> a
forall a. [Char] -> a
errorWithoutStackTrace
  [Char]
"runSafeError: Escaped exception! Unless you've imported some internal \
  \modules and did something REALLY stupid, this is a bug. Make an issue about \
  \it on the GitHub repository for in-other-words."

bombIO :: String -> a
bombIO :: [Char] -> a
bombIO [Char]
str = [Char] -> a
forall a. [Char] -> a
errorWithoutStackTrace ([Char] -> a) -> [Char] -> a
forall a b. (a -> b) -> a -> b
$
  [Char]
str [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": Escaped exception! This is likely because an `async`ed exceptional \
  \computation escaped a `catching` through an `Async`. See \
  \Control.Effect.Exceptional.Exceptional. If that sounds unlikely, and you \
  \didn't import any internal modules and do something really stupid, \
  \then this could be a bug. If so, make an issue about \
  \it on the GitHub repository for in-other-words."


-- | Runs a @'SafeError' e@ effect by making use of 'IO' exceptions.
--
-- @'Derivs' ('SafeErrorToIOC' e m) = 'SafeError' e ': 'Derivs' m@
--
-- @'Prims' ('SafeErrorToIOC' e m) = 'Control.Effect.Optional.Optional' ((->) 'Control.Exception.SomeException') ': 'Prims' m@
--
-- This has a higher-rank type, as it makes use of 'SafeErrorToIOC'.
-- __This makes 'safeErrorToIO' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'safeErrorToIOSimple', which doesn't have a higher-rank type.
safeErrorToIO :: forall e m a
               . ( Eff (Embed IO) m
                 , MonadCatch m
                 )
              => SafeErrorToIOC e m a
              -> m a
safeErrorToIO :: SafeErrorToIOC e m a -> m a
safeErrorToIO SafeErrorToIOC e m a
m =
    (m (Either e a) -> (Either e a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\e
_ -> [Char] -> m a
forall a. [Char] -> a
bombIO [Char]
"safeErrorToIO") a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return)
  (m (Either e a) -> m a) -> m (Either e a) -> m a
forall a b. (a -> b) -> a -> b
$ ErrorToIOC e m a -> m (Either e a)
forall e (m :: * -> *) a.
(MonadCatch m, Eff (Embed IO) m) =>
ErrorToIOC e m a -> m (Either e a)
errorToIO
  (ErrorToIOC e m a -> m (Either e a))
-> ErrorToIOC e m a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ SafeErrorToErrorC e (ErrorToIOC' s s' e m) a
-> ErrorToIOC' s s' e m a
forall exc (m :: * -> *) a.
Eff (Error exc) m =>
SafeErrorToErrorC exc m a -> m a
safeErrorToError
  (SafeErrorToErrorC e (ErrorToIOC' s s' e m) a
 -> ErrorToIOC' s s' e m a)
-> SafeErrorToErrorC e (ErrorToIOC' s s' e m) a
-> ErrorToIOC' s s' e m a
forall a b. (a -> b) -> a -> b
$ IntroUnderC
  (SafeError e)
  '[Catch e, Throw e]
  (SafeErrorToErrorC e (ErrorToIOC' s s' e m))
  a
-> SafeErrorToErrorC e (ErrorToIOC' s s' e m) a
forall (new :: [Effect]) (e :: Effect) (m :: * -> *) a.
(KnownList new, IntroConsistent '[e] new m) =>
IntroUnderC e new m a -> m a
introUnder
  (IntroUnderC
   (SafeError e)
   '[Catch e, Throw e]
   (SafeErrorToErrorC e (ErrorToIOC' s s' e m))
   a
 -> SafeErrorToErrorC e (ErrorToIOC' s s' e m) a)
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (SafeErrorToErrorC e (ErrorToIOC' s s' e m))
     a
-> SafeErrorToErrorC e (ErrorToIOC' s s' e m) a
forall a b. (a -> b) -> a -> b
$ SafeErrorToIOC' s s' e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (SafeErrorToErrorC e (ErrorToIOC' s s' e m))
     a
forall s s' exc (m :: * -> *) a.
SafeErrorToIOC' s s' exc m a
-> IntroUnderC
     (SafeError exc)
     '[Catch exc, Throw exc]
     (SafeErrorToErrorC exc (ErrorToIOC' s s' exc m))
     a
unSafeErrorToIOC'
  (SafeErrorToIOC' s s' e m a
 -> IntroUnderC
      (SafeError e)
      '[Catch e, Throw e]
      (SafeErrorToErrorC e (ErrorToIOC' s s' e m))
      a)
-> SafeErrorToIOC' s s' e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (SafeErrorToErrorC e (ErrorToIOC' s s' e m))
     a
forall a b. (a -> b) -> a -> b
$ SafeErrorToIOC' s s' e m a
SafeErrorToIOC e m a
m
{-# INLINE safeErrorToIO #-}


-- | Runs a @'SafeError' e@ effect by transforming it into 'ErrorIO'
-- and @'Embed' IO@.
--
-- This has a higher-rank type, as it makes use of 'SafeErrorToErrorIOC'.
-- __This makes 'safeErrorToErrorIO' very difficult to use partially applied.__
-- __In particular, it can't be composed using @'.'@.__
--
-- If performance is secondary, consider using the slower
-- 'safeErrorToErrorIOSimple', which doesn't have a higher-rank type.
safeErrorToErrorIO :: forall e m a
                    . Effs '[Embed IO, ErrorIO] m
                   => SafeErrorToErrorIOC e m a
                   -> m a
safeErrorToErrorIO :: SafeErrorToErrorIOC e m a -> m a
safeErrorToErrorIO SafeErrorToErrorIOC e m a
m =
    (m (Either e a) -> (Either e a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\e
_ -> [Char] -> m a
forall a. [Char] -> a
bombIO [Char]
"safeErrorToErrorIO") a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return)
  (m (Either e a) -> m a) -> m (Either e a) -> m a
forall a b. (a -> b) -> a -> b
$ InterpretErrorC e m a -> m (Either e a)
forall e (m :: * -> *) a.
Effs '[ErrorIO, Embed IO] m =>
InterpretErrorC e m a -> m (Either e a)
errorToErrorIO
  (InterpretErrorC e m a -> m (Either e a))
-> InterpretErrorC e m a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ SafeErrorToErrorC e (InterpretErrorC' s s' e m) a
-> InterpretErrorC' s s' e m a
forall exc (m :: * -> *) a.
Eff (Error exc) m =>
SafeErrorToErrorC exc m a -> m a
safeErrorToError
  (SafeErrorToErrorC e (InterpretErrorC' s s' e m) a
 -> InterpretErrorC' s s' e m a)
-> SafeErrorToErrorC e (InterpretErrorC' s s' e m) a
-> InterpretErrorC' s s' e m a
forall a b. (a -> b) -> a -> b
$ IntroUnderC
  (SafeError e)
  '[Catch e, Throw e]
  (SafeErrorToErrorC e (InterpretErrorC' s s' e m))
  a
-> SafeErrorToErrorC e (InterpretErrorC' s s' e m) a
forall (new :: [Effect]) (e :: Effect) (m :: * -> *) a.
(KnownList new, IntroConsistent '[e] new m) =>
IntroUnderC e new m a -> m a
introUnder
  (IntroUnderC
   (SafeError e)
   '[Catch e, Throw e]
   (SafeErrorToErrorC e (InterpretErrorC' s s' e m))
   a
 -> SafeErrorToErrorC e (InterpretErrorC' s s' e m) a)
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (SafeErrorToErrorC e (InterpretErrorC' s s' e m))
     a
-> SafeErrorToErrorC e (InterpretErrorC' s s' e m) a
forall a b. (a -> b) -> a -> b
$ SafeErrorToErrorIOC' s s' e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (SafeErrorToErrorC e (InterpretErrorC' s s' e m))
     a
forall s s' exc (m :: * -> *) a.
SafeErrorToErrorIOC' s s' exc m a
-> IntroUnderC
     (SafeError exc)
     '[Catch exc, Throw exc]
     (SafeErrorToErrorC exc (InterpretErrorC' s s' exc m))
     a
unSafeErrorToErrorIOC'
  (SafeErrorToErrorIOC' s s' e m a
 -> IntroUnderC
      (SafeError e)
      '[Catch e, Throw e]
      (SafeErrorToErrorC e (InterpretErrorC' s s' e m))
      a)
-> SafeErrorToErrorIOC' s s' e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (SafeErrorToErrorC e (InterpretErrorC' s s' e m))
     a
forall a b. (a -> b) -> a -> b
$ SafeErrorToErrorIOC' s s' e m a
SafeErrorToErrorIOC e m a
m
{-# INLINE safeErrorToErrorIO #-}

-- | Runs a @'SafeError' e@ effect by making use of 'IO' exceptions.
--
-- @'Derivs' ('SafeErrorToIOSimpleC' e m) = 'SafeError' e ': 'Derivs' m@
--
-- @'Prims' ('SafeErrorToIOSimpleC' e m) = 'Control.Effect.Optional.Optional' ((->) 'Control.Exception.SomeException') ': 'Prims' m@
--
-- This is a less performant version of 'safeErrorToIO' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
safeErrorToIOSimple :: forall e m a p
                     . ( Eff (Embed IO) m
                       , MonadCatch m
                       , Threaders '[ReaderThreads] m p
                       )
                    => SafeErrorToIOSimpleC e m a
                    -> m a
safeErrorToIOSimple :: SafeErrorToIOSimpleC e m a -> m a
safeErrorToIOSimple =
     (m (Either e a) -> (Either e a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\e
_ -> [Char] -> m a
forall a. [Char] -> a
bombIO [Char]
"safeErrorToIOSimple") a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return)
  (m (Either e a) -> m a)
-> (ErrorToIOSimpleC e m a -> m (Either e a))
-> ErrorToIOSimpleC e m a
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  ErrorToIOSimpleC e m a -> m (Either e a)
forall e (m :: * -> *) a (p :: [Effect]).
(Eff (Embed IO) m, MonadCatch m, Threaders '[ReaderThreads] m p) =>
ErrorToIOSimpleC e m a -> m (Either e a)
errorToIOSimple
  (ErrorToIOSimpleC e m a -> m a)
-> (SafeErrorToErrorC e (ErrorToIOSimpleC e m) a
    -> ErrorToIOSimpleC e m a)
-> SafeErrorToErrorC e (ErrorToIOSimpleC e m) a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# SafeErrorToErrorC e (ErrorToIOSimpleC e m) a
-> ErrorToIOSimpleC e m a
forall exc (m :: * -> *) a.
Eff (Error exc) m =>
SafeErrorToErrorC exc m a -> m a
safeErrorToError
  (SafeErrorToErrorC e (ErrorToIOSimpleC e m) a -> m a)
-> (IntroUnderC
      (SafeError e)
      '[Catch e, Throw e]
      (InterpretC ExceptionalH (SafeError e) (ErrorToIOSimpleC e m))
      a
    -> SafeErrorToErrorC e (ErrorToIOSimpleC e m) a)
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (InterpretC ExceptionalH (SafeError e) (ErrorToIOSimpleC e m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderC
  (SafeError e)
  '[Catch e, Throw e]
  (InterpretC ExceptionalH (SafeError e) (ErrorToIOSimpleC e m))
  a
-> SafeErrorToErrorC e (ErrorToIOSimpleC e m) a
forall (new :: [Effect]) (e :: Effect) (m :: * -> *) a.
(KnownList new, IntroConsistent '[e] new m) =>
IntroUnderC e new m a -> m a
introUnder
  (IntroUnderC
   (SafeError e)
   '[Catch e, Throw e]
   (InterpretC ExceptionalH (SafeError e) (ErrorToIOSimpleC e m))
   a
 -> m a)
-> (SafeErrorToIOSimpleC e m a
    -> IntroUnderC
         (SafeError e)
         '[Catch e, Throw e]
         (InterpretC ExceptionalH (SafeError e) (ErrorToIOSimpleC e m))
         a)
-> SafeErrorToIOSimpleC e m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# SafeErrorToIOSimpleC e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (InterpretC ExceptionalH (SafeError e) (ErrorToIOSimpleC e m))
     a
forall exc (m :: * -> *) a.
SafeErrorToIOSimpleC exc m a
-> IntroUnderC
     (SafeError exc)
     '[Catch exc, Throw exc]
     (SafeErrorToErrorC exc (ErrorToIOSimpleC exc m))
     a
unSafeErrorToIOSimpleC
{-# INLINE safeErrorToIOSimple #-}

-- | Runs a @'SafeError' e@ effect by transforming it into 'ErrorIO'
-- and @'Embed' IO@.
--
-- This is a less performant version of 'safeErrorToErrorIO' that doesn't have
-- a higher-rank type, making it much easier to use partially applied.
safeErrorToErrorIOSimple :: forall e m a p
                          . ( Effs '[ErrorIO, Embed IO] m
                            , Threaders '[ReaderThreads] m p
                            )
                         => SafeErrorToErrorIOSimpleC e m a
                         -> m a
safeErrorToErrorIOSimple :: SafeErrorToErrorIOSimpleC e m a -> m a
safeErrorToErrorIOSimple =
     (m (Either e a) -> (Either e a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\e
_ -> [Char] -> m a
forall a. [Char] -> a
bombIO [Char]
"safeErrorToErrorIOSimple") a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return)
  (m (Either e a) -> m a)
-> (InterpretErrorSimpleC e m a -> m (Either e a))
-> InterpretErrorSimpleC e m a
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  InterpretErrorSimpleC e m a -> m (Either e a)
forall e (m :: * -> *) a (p :: [Effect]).
(Effs '[ErrorIO, Embed IO] m, Threaders '[ReaderThreads] m p) =>
InterpretErrorSimpleC e m a -> m (Either e a)
errorToErrorIOSimple
  (InterpretErrorSimpleC e m a -> m a)
-> (SafeErrorToErrorC e (InterpretErrorSimpleC e m) a
    -> InterpretErrorSimpleC e m a)
-> SafeErrorToErrorC e (InterpretErrorSimpleC e m) a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# SafeErrorToErrorC e (InterpretErrorSimpleC e m) a
-> InterpretErrorSimpleC e m a
forall exc (m :: * -> *) a.
Eff (Error exc) m =>
SafeErrorToErrorC exc m a -> m a
safeErrorToError
  (SafeErrorToErrorC e (InterpretErrorSimpleC e m) a -> m a)
-> (IntroUnderC
      (SafeError e)
      '[Catch e, Throw e]
      (InterpretC ExceptionalH (SafeError e) (InterpretErrorSimpleC e m))
      a
    -> SafeErrorToErrorC e (InterpretErrorSimpleC e m) a)
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (InterpretC ExceptionalH (SafeError e) (InterpretErrorSimpleC e m))
     a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# IntroUnderC
  (SafeError e)
  '[Catch e, Throw e]
  (InterpretC ExceptionalH (SafeError e) (InterpretErrorSimpleC e m))
  a
-> SafeErrorToErrorC e (InterpretErrorSimpleC e m) a
forall (new :: [Effect]) (e :: Effect) (m :: * -> *) a.
(KnownList new, IntroConsistent '[e] new m) =>
IntroUnderC e new m a -> m a
introUnder
  (IntroUnderC
   (SafeError e)
   '[Catch e, Throw e]
   (InterpretC ExceptionalH (SafeError e) (InterpretErrorSimpleC e m))
   a
 -> m a)
-> (SafeErrorToErrorIOSimpleC e m a
    -> IntroUnderC
         (SafeError e)
         '[Catch e, Throw e]
         (InterpretC ExceptionalH (SafeError e) (InterpretErrorSimpleC e m))
         a)
-> SafeErrorToErrorIOSimpleC e m a
-> m a
forall b a c. Coercible b a => (b -> c) -> (a -> b) -> a -> c
.# SafeErrorToErrorIOSimpleC e m a
-> IntroUnderC
     (SafeError e)
     '[Catch e, Throw e]
     (InterpretC ExceptionalH (SafeError e) (InterpretErrorSimpleC e m))
     a
forall exc (m :: * -> *) a.
SafeErrorToErrorIOSimpleC exc m a
-> IntroUnderC
     (SafeError exc)
     '[Catch exc, Throw exc]
     (SafeErrorToErrorC exc (InterpretErrorSimpleC exc m))
     a
unSafeErrorToErrorIOSimpleC
{-# INLINE safeErrorToErrorIOSimple #-}