    {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE PolyKinds #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Proxy
    -- License     :  BSD-style (see the LICENSE file in the distribution)
    --
    -- Maintainer  :  libraries@haskell.org
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Definition of a Proxy type (poly-kinded in GHC)
    --
    -- @since 4.7.0.0
    -----------------------------------------------------------------------------

    module Data.Proxy
      (
            Proxy(..), asProxyTypeOf
          , KProxy(..)
      ) where

    import GHC.Base
    import GHC.Show
    import GHC.Read
    import GHC.Enum
    import GHC.Arr

    -- $setup
    -- >>> import Data.Void
    -- >>> import Prelude

    -- | 'Proxy' is a type that holds no data, but has a phantom parameter of
    -- arbitrary type (or even kind). Its use is to provide type information, even
    -- though there is no value available of that type (or it may be too costly to
    -- create one).
    --
    -- Historically, @'Proxy' :: 'Proxy' a@ is a safer alternative to the
    -- @'undefined' :: a@ idiom.
    --
    -- >>> Proxy :: Proxy (Void, Int -> Int)
    -- Proxy
    --
    -- Proxy can even hold types of higher kinds,
    --
    -- >>> Proxy :: Proxy Either
    -- Proxy
    --
    -- >>> Proxy :: Proxy Functor
    -- Proxy
    --
    -- >>> Proxy :: Proxy complicatedStructure
    -- Proxy
    data Proxy t = Proxy deriving ( Proxy t
    forall a. a -> a -> Bounded a
    forall k (t :: k). Proxy t
    maxBound :: Proxy t
    $cmaxBound :: forall k (t :: k). Proxy t
    minBound :: Proxy t
    $cminBound :: forall k (t :: k). Proxy t
    Bounded -- ^ @since 4.7.0.0
                                  , ReadPrec [Proxy t]
    ReadPrec (Proxy t)
    ReadS [Proxy t]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    forall k (t :: k). ReadPrec [Proxy t]
    forall k (t :: k). ReadPrec (Proxy t)
    forall k (t :: k). Int -> ReadS (Proxy t)
    forall k (t :: k). ReadS [Proxy t]
    readListPrec :: ReadPrec [Proxy t]
    $creadListPrec :: forall k (t :: k). ReadPrec [Proxy t]
    readPrec :: ReadPrec (Proxy t)
    $creadPrec :: forall k (t :: k). ReadPrec (Proxy t)
    readList :: ReadS [Proxy t]
    $creadList :: forall k (t :: k). ReadS [Proxy t]
    readsPrec :: Int -> ReadS (Proxy t)
    $creadsPrec :: forall k (t :: k). Int -> ReadS (Proxy t)
    Read    -- ^ @since 4.7.0.0
                                  )

    -- | A concrete, promotable proxy type, for use at the kind level.
    -- There are no instances for this because it is intended at the kind level only
    data KProxy (t :: Type) = KProxy

    -- It's common to use (undefined :: Proxy t) and (Proxy :: Proxy t)
    -- interchangeably, so all of these instances are hand-written to be
    -- lazy in Proxy arguments.

    -- | @since 4.7.0.0
    instance Eq (Proxy s) where
      Proxy s
    _ == :: Proxy s -> Proxy s -> Bool
    == Proxy s
    _ = Bool
    True

    -- | @since 4.7.0.0
    instance Ord (Proxy s) where
      compare :: Proxy s -> Proxy s -> Ordering
    compare Proxy s
    _ Proxy s
    _ = Ordering
    EQ

    -- | @since 4.7.0.0
    instance Show (Proxy s) where
      showsPrec :: Int -> Proxy s -> ShowS
    showsPrec Int
    _ Proxy s
    _ = String -> ShowS
    showString String
    "Proxy"

    -- | @since 4.7.0.0
    instance Enum (Proxy s) where
        succ :: Proxy s -> Proxy s
    succ Proxy s
    _               = forall a. String -> a
    errorWithoutStackTrace String
    "Proxy.succ"
        pred :: Proxy s -> Proxy s
    pred Proxy s
    _               = forall a. String -> a
    errorWithoutStackTrace String
    "Proxy.pred"
        fromEnum :: Proxy s -> Int
    fromEnum Proxy s
    _           = Int
    0
        toEnum :: Int -> Proxy s
    toEnum Int
    0             = forall k (t :: k). Proxy t
    Proxy
        toEnum Int
    _             = forall a. String -> a
    errorWithoutStackTrace String
    "Proxy.toEnum: 0 expected"
        enumFrom :: Proxy s -> [Proxy s]
    enumFrom Proxy s
    _           = [forall k (t :: k). Proxy t
    Proxy]
        enumFromThen :: Proxy s -> Proxy s -> [Proxy s]
    enumFromThen Proxy s
    _ Proxy s
    _     = [forall k (t :: k). Proxy t
    Proxy]
        enumFromThenTo :: Proxy s -> Proxy s -> Proxy s -> [Proxy s]
    enumFromThenTo Proxy s
    _ Proxy s
    _ Proxy s
    _ = [forall k (t :: k). Proxy t
    Proxy]
        enumFromTo :: Proxy s -> Proxy s -> [Proxy s]
    enumFromTo Proxy s
    _ Proxy s
    _       = [forall k (t :: k). Proxy t
    Proxy]

    -- | @since 4.7.0.0
    instance Ix (Proxy s) where
        range :: (Proxy s, Proxy s) -> [Proxy s]
    range (Proxy s, Proxy s)
    _           = [forall k (t :: k). Proxy t
    Proxy]
        index :: (Proxy s, Proxy s) -> Proxy s -> Int
    index (Proxy s, Proxy s)
    _ Proxy s
    _         = Int
    0
        inRange :: (Proxy s, Proxy s) -> Proxy s -> Bool
    inRange (Proxy s, Proxy s)
    _ Proxy s
    _       = Bool
    True
        rangeSize :: (Proxy s, Proxy s) -> Int
    rangeSize (Proxy s, Proxy s)
    _       = Int
    1
        unsafeIndex :: (Proxy s, Proxy s) -> Proxy s -> Int
    unsafeIndex (Proxy s, Proxy s)
    _ Proxy s
    _   = Int
    0
        unsafeRangeSize :: (Proxy s, Proxy s) -> Int
    unsafeRangeSize (Proxy s, Proxy s)
    _ = Int
    1

    -- | @since 4.9.0.0
    instance Semigroup (Proxy s) where
        Proxy s
    _ <> :: Proxy s -> Proxy s -> Proxy s
    <> Proxy s
    _ = forall k (t :: k). Proxy t
    Proxy
        sconcat :: NonEmpty (Proxy s) -> Proxy s
    sconcat NonEmpty (Proxy s)
    _ = forall k (t :: k). Proxy t
    Proxy
        stimes :: forall b. Integral b => b -> Proxy s -> Proxy s
    stimes b
    _ Proxy s
    _ = forall k (t :: k). Proxy t
    Proxy

    -- | @since 4.7.0.0
    instance Monoid (Proxy s) where
        mempty :: Proxy s
    mempty = forall k (t :: k). Proxy t
    Proxy
        mconcat :: [Proxy s] -> Proxy s
    mconcat [Proxy s]
    _ = forall k (t :: k). Proxy t
    Proxy

    -- | @since 4.7.0.0
    instance Functor Proxy where
        fmap :: forall a b. (a -> b) -> Proxy a -> Proxy b
    fmap a -> b
    _ Proxy a
    _ = forall k (t :: k). Proxy t
    Proxy
        {-# INLINE fmap #-}

    -- | @since 4.7.0.0
    instance Applicative Proxy where
        pure :: forall a. a -> Proxy a
    pure a
    _ = forall k (t :: k). Proxy t
    Proxy
        {-# INLINE pure #-}
        Proxy (a -> b)
    _ <*> :: forall a b. Proxy (a -> b) -> Proxy a -> Proxy b
    <*> Proxy a
    _ = forall k (t :: k). Proxy t
    Proxy
        {-# INLINE (<*>) #-}

    -- | @since 4.9.0.0
    instance Alternative Proxy where
        empty :: forall a. Proxy a
    empty = forall k (t :: k). Proxy t
    Proxy
        {-# INLINE empty #-}
        Proxy a
    _ <|> :: forall a. Proxy a -> Proxy a -> Proxy a
    <|> Proxy a
    _ = forall k (t :: k). Proxy t
    Proxy
        {-# INLINE (<|>) #-}

    -- | @since 4.7.0.0
    instance Monad Proxy where
        Proxy a
    _ >>= :: forall a b. Proxy a -> (a -> Proxy b) -> Proxy b
    >>= a -> Proxy b
    _ = forall k (t :: k). Proxy t
    Proxy
        {-# INLINE (>>=) #-}

    -- | @since 4.9.0.0
    instance MonadPlus Proxy

    -- | 'asProxyTypeOf' is a type-restricted version of 'const'.
    -- It is usually used as an infix operator, and its typing forces its first
    -- argument (which is usually overloaded) to have the same type as the tag
    -- of the second.
    --
    -- >>> import Data.Word
    -- >>> :type asProxyTypeOf 123 (Proxy :: Proxy Word8)
    -- asProxyTypeOf 123 (Proxy :: Proxy Word8) :: Word8
    --
    -- Note the lower-case @proxy@ in the definition. This allows any type
    -- constructor with just one argument to be passed to the function, for example
    -- we could also write
    --
    -- >>> import Data.Word
    -- >>> :type asProxyTypeOf 123 (Just (undefined :: Word8))
    -- asProxyTypeOf 123 (Just (undefined :: Word8)) :: Word8
    asProxyTypeOf :: a -> proxy a -> a
    asProxyTypeOf :: forall a (proxy :: * -> *). a -> proxy a -> a
    asProxyTypeOf = forall a b. a -> b -> a
    const
    {-# INLINE asProxyTypeOf #-}