    {-# LANGUAGE CPP #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE MultiParamTypeClasses #-}

    #if __GLASGOW_HASKELL__ >= 710
    {-# LANGUAGE PatternSynonyms #-}
    {-# LANGUAGE ViewPatterns #-}
    #endif

    #ifndef MIN_VERSION_base
    #define MIN_VERSION_base(x,y,z) 1
    #endif

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  System.Exit.Lens
    -- Copyright   :  (C) 2013-16 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  Control.Exception
    --
    -- These prisms can be used with the combinators in "Control.Exception.Lens".
    ----------------------------------------------------------------------------
    module System.Exit.Lens
      ( AsExitCode(..)
      , _ExitFailure
      , _ExitSuccess
    #if __GLASGOW_HASKELL__ >= 710
      , pattern ExitFailure_
      , pattern ExitSuccess_
    #endif
      ) where

    import Control.Exception
    import Control.Exception.Lens
    import Control.Lens
    import System.Exit

    #if !MIN_VERSION_base(4,8,0)
    import Control.Applicative
    #endif

    -- | Exit codes that a program can return with:
    class AsExitCode t where
      _ExitCode :: Prism' t ExitCode

    instance AsExitCode ExitCode where
      _ExitCode :: p ExitCode (f ExitCode) -> p ExitCode (f ExitCode)
    _ExitCode = p ExitCode (f ExitCode) -> p ExitCode (f ExitCode)
    forall a. a -> a
    id
      {-# INLINE _ExitCode #-}

    instance AsExitCode SomeException where
      _ExitCode :: p ExitCode (f ExitCode) -> p SomeException (f SomeException)
    _ExitCode = p ExitCode (f ExitCode) -> p SomeException (f SomeException)
    forall a. Exception a => Prism' SomeException a
    exception
      {-# INLINE _ExitCode #-}

    -- | indicates successful termination;
    --
    -- @
    -- '_ExitSuccess' :: 'Prism'' 'ExitCode'      ()
    -- '_ExitSuccess' :: 'Prism'' 'SomeException' ()
    -- @
    _ExitSuccess :: AsExitCode t => Prism' t ()
    _ExitSuccess :: Prism' t ()
    _ExitSuccess = p ExitCode (f ExitCode) -> p t (f t)
    forall t. AsExitCode t => Prism' t ExitCode
    _ExitCode (p ExitCode (f ExitCode) -> p t (f t))
    -> (p () (f ()) -> p ExitCode (f ExitCode))
    -> p () (f ())
    -> p t (f t)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ExitCode -> Either (f ExitCode) ())
    -> (Either (f ExitCode) (f ExitCode) -> f ExitCode)
    -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
    -> p ExitCode (f ExitCode)
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap ExitCode -> Either (f ExitCode) ()
    forall (f :: * -> *).
    Applicative f =>
    ExitCode -> Either (f ExitCode) ()
    seta ((f ExitCode -> f ExitCode)
    -> (f ExitCode -> f ExitCode)
    -> Either (f ExitCode) (f ExitCode)
    -> f ExitCode
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either f ExitCode -> f ExitCode
    forall a. a -> a
    id f ExitCode -> f ExitCode
    forall a. a -> a
    id) (p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
     -> p ExitCode (f ExitCode))
    -> (p () (f ())
        -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode)))
    -> p () (f ())
    -> p ExitCode (f ExitCode)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . p () (f ExitCode)
    -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
    forall (p :: * -> * -> *) a b c.
    Choice p =>
    p a b -> p (Either c a) (Either c b)
    right' (p () (f ExitCode)
     -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode)))
    -> (p () (f ()) -> p () (f ExitCode))
    -> p () (f ())
    -> p (Either (f ExitCode) ()) (Either (f ExitCode) (f ExitCode))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (f () -> f ExitCode) -> p () (f ()) -> p () (f ExitCode)
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap (ExitCode
    ExitSuccess ExitCode -> f () -> f ExitCode
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$) where
      seta :: ExitCode -> Either (f ExitCode) ()
    seta ExitSuccess = () -> Either (f ExitCode) ()
    forall a b. b -> Either a b
    Right ()
      seta t :: ExitCode
    t           = f ExitCode -> Either (f ExitCode) ()
    forall a b. a -> Either a b
    Left  (ExitCode -> f ExitCode
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ExitCode
    t)
    {-# INLINE _ExitSuccess #-}

    -- | indicates program failure with an exit code. The exact interpretation of the code is operating-system dependent. In particular, some values may be prohibited (e.g. 0 on a POSIX-compliant system).
    --
    -- @
    -- '_ExitFailure' :: 'Prism'' 'ExitCode'      'Int'
    -- '_ExitFailure' :: 'Prism'' 'SomeException' 'Int'
    -- @
    _ExitFailure :: AsExitCode t => Prism' t Int
    _ExitFailure :: Prism' t Int
    _ExitFailure = p ExitCode (f ExitCode) -> p t (f t)
    forall t. AsExitCode t => Prism' t ExitCode
    _ExitCode (p ExitCode (f ExitCode) -> p t (f t))
    -> (p Int (f Int) -> p ExitCode (f ExitCode))
    -> p Int (f Int)
    -> p t (f t)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ExitCode -> Either (f ExitCode) Int)
    -> (Either (f ExitCode) (f ExitCode) -> f ExitCode)
    -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
    -> p ExitCode (f ExitCode)
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap ExitCode -> Either (f ExitCode) Int
    forall (f :: * -> *).
    Applicative f =>
    ExitCode -> Either (f ExitCode) Int
    seta ((f ExitCode -> f ExitCode)
    -> (f ExitCode -> f ExitCode)
    -> Either (f ExitCode) (f ExitCode)
    -> f ExitCode
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either f ExitCode -> f ExitCode
    forall a. a -> a
    id f ExitCode -> f ExitCode
    forall a. a -> a
    id) (p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
     -> p ExitCode (f ExitCode))
    -> (p Int (f Int)
        -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode)))
    -> p Int (f Int)
    -> p ExitCode (f ExitCode)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . p Int (f ExitCode)
    -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
    forall (p :: * -> * -> *) a b c.
    Choice p =>
    p a b -> p (Either c a) (Either c b)
    right' (p Int (f ExitCode)
     -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode)))
    -> (p Int (f Int) -> p Int (f ExitCode))
    -> p Int (f Int)
    -> p (Either (f ExitCode) Int) (Either (f ExitCode) (f ExitCode))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (f Int -> f ExitCode) -> p Int (f Int) -> p Int (f ExitCode)
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap ((Int -> ExitCode) -> f Int -> f ExitCode
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Int -> ExitCode
    ExitFailure) where
      seta :: ExitCode -> Either (f ExitCode) Int
    seta (ExitFailure i :: Int
    i) = Int -> Either (f ExitCode) Int
    forall a b. b -> Either a b
    Right Int
    i
      seta t :: ExitCode
    t               = f ExitCode -> Either (f ExitCode) Int
    forall a b. a -> Either a b
    Left  (ExitCode -> f ExitCode
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ExitCode
    t)
    {-# INLINE _ExitFailure #-}

    #if __GLASGOW_HASKELL__ >= 710
    pattern $bExitSuccess_ :: s
    $mExitSuccess_ :: forall r s. AsExitCode s => s -> (Void# -> r) -> (Void# -> r) -> r
    ExitSuccess_ <- (has _ExitSuccess -> True) where
      ExitSuccess_ = AReview s () -> () -> s
    forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
    review AReview s ()
    forall t. AsExitCode t => Prism' t ()
    _ExitSuccess ()

    pattern $bExitFailure_ :: Int -> s
    $mExitFailure_ :: forall r s. AsExitCode s => s -> (Int -> r) -> (Void# -> r) -> r
    ExitFailure_ a <- (preview _ExitFailure -> Just a) where
      ExitFailure_ a :: Int
    a = AReview s Int -> Int -> s
    forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
    review AReview s Int
    forall t. AsExitCode t => Prism' t Int
    _ExitFailure Int
    a
    #endif