-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Utility package for constraints
--   
--   Convenience functions and TH for working with constraints. See
--   README.md for example usage.
@package constraints-extras
@version 0.4.0.2

module Data.Constraint.Compose

-- | Composition for constraints.
class p f a => ComposeC (p :: k2 -> Constraint) (f :: k1 -> k2) (a :: k1)
instance forall k2 k1 (p :: k2 -> GHC.Types.Constraint) (f :: k1 -> k2) (a :: k1). p (f a) => Data.Constraint.Compose.ComposeC p f a

module Data.Constraint.Flip

-- | Flip for constraints.
class c h g => FlipC (c :: k -> k' -> Constraint) (g :: k') (h :: k)
instance forall k k' (c :: k -> k' -> GHC.Types.Constraint) (h :: k) (g :: k'). c h g => Data.Constraint.Flip.FlipC c g h

-- | Throughout this module, we use the following GADT and ArgDict
--   instance in our examples:
--   
--   
--   {-# LANGUAGE StandaloneDeriving #-}
--   
--   data Tag a where
--     I :: Tag Int
--     B :: Tag Bool
--   deriving instance Show (Tag a)
--   
--   $(deriveArgDict ''Tag)
--   
--   
--   The constructors of Tag mean that a type variable a
--   in Tag a must come from the set { Int, Bool
--   }. We call this the "set of types a that could be applied to
--   Tag".
module Data.Constraint.Extras

-- | The constraint Has c f means that given any value of type
--   f a, we can determine that there is an instance of c
--   a. For example, Has Show Tag means that given any x
--   :: Tag a, we can conclude Show a. Most commonly, the
--   type f will be a GADT, where we can enumerate all the
--   possible index types through pattern matching, and discover that there
--   is an appropriate instance in each case. In this sort of situation,
--   the c can be left entirely polymorphic in the instance for
--   Has, and this is the sort of instance that the provided
--   Template Haskell code writes.
class Has (c :: k -> Constraint) (f :: k -> Type)

-- | Use the f a to show that there is an instance of c
--   a, and bring it into scope.
--   
--   The order of type variables is chosen to work with
--   -XTypeApplications.
--   
--   
--   -- Hold a value of type a, along with a tag identifying the a.
--   data SomeTagged tag where
--     SomeTagged :: a -> tag a -> SomeTagged tag
--   
--   -- Use the stored tag to identify the thing we have, allowing us to call 'show'. Note that we
--   -- have no knowledge of the tag type.
--   showSomeTagged :: Has Show tag => SomeTagged tag -> String
--   showSomeTagged (SomeTagged a tag) = has @Show tag $ show a
--   
has :: forall (a :: k) r. Has c f => f a -> (c a => r) -> r

-- | Use an f a to obtain a dictionary for c a
--   
--   
--   argDict @Show I :: Dict (Show Int)
--   
argDict :: forall (a :: k). Has c f => f a -> Dict (c a)

-- | Get a dictionary for c (g a), using a value of type f
--   a.
--   
--   
--   argDict' @Show @Identity B :: Dict (Show (Identity Bool))
--   
argDict' :: forall {k} {k'} c (g :: k' -> k) f (a :: k'). Has' c f g => f a -> Dict (c (g a))

-- | Get a dictionary for c (v g), using a value of type f
--   v.
argDictV :: forall {k'} {k2} f c (g :: k') (v :: k' -> k2). HasV c f g => f v -> Dict (c (v g))

-- | The constraint Has' c f g means that given a value of type
--   f a, we can satisfy the constraint c (g a).
type Has' (c :: k -> Constraint) (f :: k' -> Type) (g :: k' -> k) = Has ComposeC c g f

-- | Like has, but we get a c (g a) instance brought into
--   scope instead. Use -XTypeApplications to specify c
--   and g.
--   
--   
--   -- From dependent-sum:Data.Dependent.Sum
--   data DSum tag f = forall a. !(tag a) :=> f a
--   
--   -- Show the value from a dependent sum. (We'll need 'whichever', discussed later, to show the key.)
--   showDSumVal :: forall tag f . Has' Show tag f => DSum tag f -> String
--   showDSumVal (tag :=> fa) = has' @Show @f tag $ show fa
--   
has' :: forall {k} {k'} c (g :: k' -> k) f (a :: k') r. Has' c f g => f a -> (c (g a) => r) -> r

-- | The constraint HasV c f g means that given a value of type
--   f v, we can satisfy the constraint c (v g).
type HasV (c :: k2 -> Constraint) (f :: k' -> k2 -> Type) (g :: k') = Has FlipC ComposeC c :: k' -> k2 -> k' -> Constraint g f

-- | Similar to has, but given a value of type f v, we get
--   a c (v g) instance brought into scope instead.
hasV :: forall {k2} {k'} c (g :: k') f (v :: k' -> k2) r. HasV c f g => f v -> (c (v g) => r) -> r

-- | Given "forall a. c (t a)" (the ForallF c t
--   constraint), select a specific a, and bring c (t a)
--   into scope. Use -XTypeApplications to specify c,
--   t and a.
--   
--   
--   -- Show the tag of a dependent sum, even though we don't know the tag type.
--   showDSumKey :: forall tag f . ForallF Show tag => DSum tag f -> String
--   showDSumKey ((tag :: tag a) :=> fa) = whichever @Show @tag @a $ show tag
--   
whichever :: forall {k2} {k1} c (t :: k1 -> k2) (a :: k1) r. ForallF c t => (c (t a) => r) -> r

-- | Allows explicit specification of constraint implication.
class Implies1 (c :: k -> Constraint) (d :: k -> Constraint)
implies1 :: forall (a :: k). Implies1 c d => c a :- d a
instance forall k (c :: k -> GHC.Types.Constraint) (f :: k -> *) (g :: k -> *). (Data.Constraint.Extras.Has c f, Data.Constraint.Extras.Has c g) => Data.Constraint.Extras.Has c (f GHC.Internal.Generics.:+: g)
instance forall k (c :: k -> GHC.Types.Constraint) (f :: k -> *) (g :: k -> *). (Data.Constraint.Extras.Has c f, Data.Constraint.Extras.Has c g) => Data.Constraint.Extras.Has c (Data.Functor.Sum.Sum f g)

module Data.Constraint.Extras.TH
deriveArgDict :: Name -> Q [Dec]

-- | Deprecated: Just use deriveArgDict
deriveArgDictV :: Name -> Q [Dec]
gadtIndices :: Name -> [Con] -> Q [Either Type Type]
