    module Hackage.Security.Util.Exit where

    import Prelude
    import Control.Monad (liftM)
    import Control.Monad.Except (ExceptT, runExceptT, throwError)

    {-------------------------------------------------------------------------------
      Auxiliary: multiple exit points
    -------------------------------------------------------------------------------}

    -- | Multiple exit points
    --
    -- We can simulate the imperative code
    --
    -- > if (cond1)
    -- >   return exp1;
    -- > if (cond2)
    -- >   return exp2;
    -- > if (cond3)
    -- >   return exp3;
    -- > return exp4;
    --
    -- as
    --
    -- > multipleExitPoints $ do
    -- >   when (cond1) $
    -- >     exit exp1
    -- >   when (cond2) $
    -- >     exit exp2
    -- >   when (cond3) $
    -- >     exit exp3
    -- >   return exp4
    multipleExitPoints :: Monad m => ExceptT a m a -> m a
    multipleExitPoints :: forall (m :: * -> *) a. Monad m => ExceptT a m a -> m a
    multipleExitPoints = (Either a a -> a) -> m (Either a a) -> m a
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM Either a a -> a
    forall a. Either a a -> a
    aux (m (Either a a) -> m a)
    -> (ExceptT a m a -> m (Either a a)) -> ExceptT a m a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ExceptT a m a -> m (Either a a)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT
      where
        aux :: Either a a -> a
        aux :: forall a. Either a a -> a
    aux (Left  a
    a) = a
    a
        aux (Right a
    a) = a
    a

    -- | Function exit point (see 'multipleExitPoints')
    exit :: Monad m => e -> ExceptT e m a
    exit :: forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
    exit = e -> ExceptT e m a
    forall a. e -> ExceptT e m a
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError