-- | Provider of the 'MonadFail' instance for 'Eff'.
module Effectful.Fail
  ( -- * Effect
    Fail(..)

    -- ** Handlers
  , runFail
  , runFailIO
  ) where

import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.Error.Static
import Effectful.Internal.Monad (Fail(..))

-- | Run the 'Fail' effect via 'Error'.
runFail :: HasCallStack => Eff (Fail : es) a -> Eff es (Either String a)
runFail :: forall (es :: [(Type -> Type) -> Type -> Type]) a.
HasCallStack =>
Eff (Fail : es) a -> Eff es (Either String a)
runFail = (Eff (Error String : es) a -> Eff es (Either String a))
-> (forall {a} {localEs :: [(Type -> Type) -> Type -> Type]}.
    HasCallStack =>
    Fail (Eff localEs) a -> Eff (Error String : es) a)
-> Eff (Fail : es) a
-> Eff es (Either String a)
forall (e :: (Type -> Type) -> Type -> Type)
       (handlerEs :: [(Type -> Type) -> Type -> Type]) a
       (es :: [(Type -> Type) -> Type -> Type]) b.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler_ e handlerEs -> Eff (e : es) a -> Eff es b
reinterpret_ Eff (Error String : es) a -> Eff es (Either String a)
forall e (es :: [(Type -> Type) -> Type -> Type]) a.
HasCallStack =>
Eff (Error e : es) a -> Eff es (Either e a)
runErrorNoCallStack ((forall {a} {localEs :: [(Type -> Type) -> Type -> Type]}.
  HasCallStack =>
  Fail (Eff localEs) a -> Eff (Error String : es) a)
 -> Eff (Fail : es) a -> Eff es (Either String a))
-> (forall {a} {localEs :: [(Type -> Type) -> Type -> Type]}.
    HasCallStack =>
    Fail (Eff localEs) a -> Eff (Error String : es) a)
-> Eff (Fail : es) a
-> Eff es (Either String a)
forall a b. (a -> b) -> a -> b
$ \case
  Fail String
msg -> String -> Eff (Error String : es) a
forall e (es :: [(Type -> Type) -> Type -> Type]) a.
(HasCallStack, Error e :> es, Show e) =>
e -> Eff es a
throwError String
msg

-- | Run the 'Fail' effect via the 'MonadFail' instance for 'IO'.
runFailIO :: (HasCallStack, IOE :> es) => Eff (Fail : es) a -> Eff es a
runFailIO :: forall (es :: [(Type -> Type) -> Type -> Type]) a.
(HasCallStack, IOE :> es) =>
Eff (Fail : es) a -> Eff es a
runFailIO = EffectHandler_ Fail es -> Eff (Fail : es) a -> Eff es a
forall (e :: (Type -> Type) -> Type -> Type)
       (es :: [(Type -> Type) -> Type -> Type]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
EffectHandler_ e es -> Eff (e : es) a -> Eff es a
interpret_ (EffectHandler_ Fail es -> Eff (Fail : es) a -> Eff es a)
-> EffectHandler_ Fail es -> Eff (Fail : es) a -> Eff es a
forall a b. (a -> b) -> a -> b
$ \case
  Fail String
msg -> IO a -> Eff es a
forall a. IO a -> Eff es a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO a -> Eff es a) -> IO a -> Eff es a
forall a b. (a -> b) -> a -> b
$ String -> IO a
forall a. String -> IO a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
msg