{- Language/Haskell/TH/Desugar/Util.hs

(c) Richard Eisenberg 2013
rae@cs.brynmawr.edu

Utility functions for th-desugar package.
-}

{-# LANGUAGE CPP, DeriveDataTypeable, DeriveGeneric, DeriveLift, RankNTypes,
             ScopedTypeVariables, TupleSections, AllowAmbiguousTypes,
             TemplateHaskellQuotes, TypeApplications, MagicHash #-}

module Language.Haskell.TH.Desugar.Util (
  newUniqueName,
  impossible,
  nameOccursIn, allNamesIn, mkTypeName, mkDataName, mkNameWith, isDataName,
  stripVarP_maybe, extractBoundNamesStmt,
  concatMapM, mapAccumLM, mapMaybeM, expectJustM,
  stripPlainTV_maybe, extractTvbKind_maybe,
  thirdOf3, splitAtList, extractBoundNamesDec,
  extractBoundNamesPat,
  tvbToType, tvbToTypeWithSig,
  nameMatches, thdOf3, liftFst, liftSnd, firstMatch, firstMatchM,
  tupleNameDegree_maybe,
  unboxedSumNameDegree_maybe, unboxedTupleNameDegree_maybe, splitTuple_maybe,
  topEverywhereM, isInfixDataCon,
  isTypeKindName, typeKindName,
  unSigType, unfoldType, ForallTelescope(..), FunArgs(..), VisFunArg(..),
  filterVisFunArgs, ravelType, unravelType,
  TypeArg(..), applyType, filterTANormals, probablyWrongUnTypeArg,
  tyVarBndrVisToTypeArg, tyVarBndrVisToTypeArgWithSig,
  bindIP,
  DataFlavor(..),
  freeKindVariablesWellScoped,
  ForAllTyFlag(..), tvbForAllTyFlagsToSpecs, tvbForAllTyFlagsToBndrVis,
  matchUpSAKWithDecl
  ) where

import Prelude hiding (mapM, foldl, concatMap, any)

import Language.Haskell.TH hiding ( cxt )
import Language.Haskell.TH.Datatype
import Language.Haskell.TH.Datatype.TyVarBndr
import qualified Language.Haskell.TH.Desugar.OSet as OS
import Language.Haskell.TH.Desugar.OSet (OSet)
import Language.Haskell.TH.Instances ()
import Language.Haskell.TH.Syntax

import qualified Control.Monad.Fail as Fail
import Data.Foldable
import Data.Function ( on )
import Data.Generics ( Data, Typeable, everything, extM, gmapM, mkQ )
import qualified Data.Kind as Kind
import qualified Data.List as List
import qualified Data.Map as Map
import Data.Map ( Map )
import Data.Maybe
import qualified Data.Set as Set
import Data.Traversable
import GHC.Classes ( IP )
import GHC.Generics ( Generic )
import Unsafe.Coerce ( unsafeCoerce )

#if __GLASGOW_HASKELL__ >= 900
import Language.Haskell.TH.Ppr ( PprFlag(..) )
import qualified Language.Haskell.TH.PprLib as Ppr
#endif

#if __GLASGOW_HASKELL__ >= 906
import GHC.Tuple ( Solo(MkSolo) )
#elif __GLASGOW_HASKELL__ >= 900
import GHC.Tuple ( Solo(Solo) )
#endif

#if __GLASGOW_HASKELL__ >= 908
import GHC.Tuple ( Tuple0, Unit )
import Text.Read ( readMaybe )
#endif

#if __GLASGOW_HASKELL__ >= 910
import GHC.Types ( Solo#, Sum2#, Tuple0#, Unit# )
#endif

----------------------------------------
-- TH manipulations
----------------------------------------

-- | Like newName, but even more unique (unique across different splices),
-- and with unique @nameBase@s. Precondition: the string is a valid Haskell
-- alphanumeric identifier (could be upper- or lower-case).
newUniqueName :: Quasi q => String -> q Name
newUniqueName :: forall (q :: * -> *). Quasi q => String -> q Name
newUniqueName String
str = do
  Name
n <- String -> q Name
forall (q :: * -> *). Quasi q => String -> q Name
qNewName String
str
  String -> q Name
forall (q :: * -> *). Quasi q => String -> q Name
qNewName (String -> q Name) -> String -> q Name
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
n

-- | @mkNameWith lookup_fun mkName_fun str@ looks up the exact 'Name' of @str@
-- using the function @lookup_fun@. If it finds 'Just' the 'Name', meaning
-- that it is bound in the current scope, then it is returned. If it finds
-- 'Nothing', it assumes that @str@ is declared in the current module, and
-- uses @mkName_fun@ to construct the appropriate 'Name' to return.
mkNameWith :: Quasi q => (String -> q (Maybe Name))
                      -> (String -> String -> String -> Name)
                      -> String -> q Name
mkNameWith :: forall (q :: * -> *).
Quasi q =>
(String -> q (Maybe Name))
-> (String -> String -> String -> Name) -> String -> q Name
mkNameWith String -> q (Maybe Name)
lookup_fun String -> String -> String -> Name
mkName_fun String
str = do
  Maybe Name
m_name <- String -> q (Maybe Name)
lookup_fun String
str
  case Maybe Name
m_name of
    Just Name
name -> Name -> q Name
forall a. a -> q a
forall (m :: * -> *) a. Monad m => a -> m a
return Name
name
    Maybe Name
Nothing -> do
      Loc { loc_package :: Loc -> String
loc_package = String
pkg, loc_module :: Loc -> String
loc_module = String
modu } <- q Loc
forall (m :: * -> *). Quasi m => m Loc
qLocation
      Name -> q Name
forall a. a -> q a
forall (m :: * -> *) a. Monad m => a -> m a
return (Name -> q Name) -> Name -> q Name
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> Name
mkName_fun String
pkg String
modu String
str

-- | Like TH's @lookupTypeName@, but if this name is not bound, then we assume
-- it is declared in the current module.
mkTypeName :: Quasi q => String -> q Name
mkTypeName :: forall (q :: * -> *). Quasi q => String -> q Name
mkTypeName = (String -> q (Maybe Name))
-> (String -> String -> String -> Name) -> String -> q Name
forall (q :: * -> *).
Quasi q =>
(String -> q (Maybe Name))
-> (String -> String -> String -> Name) -> String -> q Name
mkNameWith (Bool -> String -> q (Maybe Name)
forall (m :: * -> *). Quasi m => Bool -> String -> m (Maybe Name)
qLookupName Bool
True) String -> String -> String -> Name
mkNameG_tc

-- | Like TH's @lookupDataName@, but if this name is not bound, then we assume
-- it is declared in the current module.
mkDataName :: Quasi q => String -> q Name
mkDataName :: forall (q :: * -> *). Quasi q => String -> q Name
mkDataName = (String -> q (Maybe Name))
-> (String -> String -> String -> Name) -> String -> q Name
forall (q :: * -> *).
Quasi q =>
(String -> q (Maybe Name))
-> (String -> String -> String -> Name) -> String -> q Name
mkNameWith (Bool -> String -> q (Maybe Name)
forall (m :: * -> *). Quasi m => Bool -> String -> m (Maybe Name)
qLookupName Bool
False) String -> String -> String -> Name
mkNameG_d

-- | Is this name a data constructor name? A 'False' answer means "unsure".
isDataName :: Name -> Bool
isDataName :: Name -> Bool
isDataName (Name OccName
_ (NameG NameSpace
DataName PkgName
_ ModName
_)) = Bool
True
isDataName Name
_                             = Bool
False

-- | Extracts the name out of a variable pattern, or returns @Nothing@
stripVarP_maybe :: Pat -> Maybe Name
stripVarP_maybe :: Pat -> Maybe Name
stripVarP_maybe (VarP Name
name) = Name -> Maybe Name
forall a. a -> Maybe a
Just Name
name
stripVarP_maybe Pat
_           = Maybe Name
forall a. Maybe a
Nothing

-- | Extracts the name out of a @PlainTV@, or returns @Nothing@
stripPlainTV_maybe :: TyVarBndr_ flag -> Maybe Name
stripPlainTV_maybe :: forall flag. TyVarBndr_ flag -> Maybe Name
stripPlainTV_maybe = (Name -> Maybe Name)
-> (Name -> Kind -> Maybe Name) -> TyVarBndr_ flag -> Maybe Name
forall r flag.
(Name -> r) -> (Name -> Kind -> r) -> TyVarBndr_ flag -> r
elimTV Name -> Maybe Name
forall a. a -> Maybe a
Just (\Name
_ Kind
_ -> Maybe Name
forall a. Maybe a
Nothing)

-- | Extracts the kind from a 'TyVarBndr'. Returns @'Just' k@ if the 'TyVarBndr'
-- is a 'KindedTV' and returns 'Nothing' if it is a 'PlainTV'.
extractTvbKind_maybe :: TyVarBndr_ flag -> Maybe Kind
extractTvbKind_maybe :: forall flag. TyVarBndr_ flag -> Maybe Kind
extractTvbKind_maybe = (Name -> Maybe Kind)
-> (Name -> Kind -> Maybe Kind) -> TyVarBndr_ flag -> Maybe Kind
forall r flag.
(Name -> r) -> (Name -> Kind -> r) -> TyVarBndr_ flag -> r
elimTV (\Name
_ -> Maybe Kind
forall a. Maybe a
Nothing) (\Name
_ Kind
k -> Kind -> Maybe Kind
forall a. a -> Maybe a
Just Kind
k)

-- | Report that a certain TH construct is impossible
impossible :: Fail.MonadFail q => String -> q a
impossible :: forall (q :: * -> *) a. MonadFail q => String -> q a
impossible String
err = String -> q a
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail (String
err String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n    This should not happen in Haskell.\n    Please email rae@cs.brynmawr.edu with your code if you see this.")

-- | Convert a 'TyVarBndr' into a 'Type', dropping the kind signature
-- (if it has one).
tvbToType :: TyVarBndr_ flag -> Type
tvbToType :: forall flag. TyVarBndr_ flag -> Kind
tvbToType = Name -> Kind
VarT (Name -> Kind)
-> (TyVarBndr_ flag -> Name) -> TyVarBndr_ flag -> Kind
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVarBndr_ flag -> Name
forall flag. TyVarBndr_ flag -> Name
tvName

-- | Convert a 'TyVarBndr' into a 'Type', preserving the kind signature
-- (if it has one).
tvbToTypeWithSig :: TyVarBndr_ flag -> Type
tvbToTypeWithSig :: forall flag. TyVarBndr_ flag -> Kind
tvbToTypeWithSig = (Name -> Kind) -> (Name -> Kind -> Kind) -> TyVarBndr_ flag -> Kind
forall r flag.
(Name -> r) -> (Name -> Kind -> r) -> TyVarBndr_ flag -> r
elimTV Name -> Kind
VarT (\Name
n Kind
k -> Kind -> Kind -> Kind
SigT (Name -> Kind
VarT Name
n) Kind
k)

-- | Do two names name the same thing?
nameMatches :: Name -> Name -> Bool
nameMatches :: Name -> Name -> Bool
nameMatches n1 :: Name
n1@(Name OccName
occ1 NameFlavour
flav1) n2 :: Name
n2@(Name OccName
occ2 NameFlavour
flav2)
  | NameFlavour
NameS <- NameFlavour
flav1 = OccName
occ1 OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== OccName
occ2
  | NameFlavour
NameS <- NameFlavour
flav2 = OccName
occ1 OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== OccName
occ2
  | NameQ ModName
mod1 <- NameFlavour
flav1
  , NameQ ModName
mod2 <- NameFlavour
flav2
  = ModName
mod1 ModName -> ModName -> Bool
forall a. Eq a => a -> a -> Bool
== ModName
mod2 Bool -> Bool -> Bool
&& OccName
occ1 OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== OccName
occ2
  | NameQ ModName
mod1 <- NameFlavour
flav1
  , NameG NameSpace
_ PkgName
_ ModName
mod2 <- NameFlavour
flav2
  = ModName
mod1 ModName -> ModName -> Bool
forall a. Eq a => a -> a -> Bool
== ModName
mod2 Bool -> Bool -> Bool
&& OccName
occ1 OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== OccName
occ2
  | NameG NameSpace
_ PkgName
_ ModName
mod1 <- NameFlavour
flav1
  , NameQ ModName
mod2 <- NameFlavour
flav2
  = ModName
mod1 ModName -> ModName -> Bool
forall a. Eq a => a -> a -> Bool
== ModName
mod2 Bool -> Bool -> Bool
&& OccName
occ1 OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== OccName
occ2
  | Bool
otherwise
  = Name
n1 Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
n2

-- | Extract the degree of a tuple 'Name'.
--
-- In addition to recognizing tuple syntax (e.g., @''(,,)@), this also
-- recognizes the following:
--
-- * @''Unit@ (for 0-tuples)
--
-- * @''Solo@/@'MkSolo@ (for 1-tuples)
--
-- * @''Tuple<N>@ (for <N>-tuples)
--
-- In recent versions of GHC, @''()@ is a synonym for @''Unit@, @''(,)@ is a
-- synonym for @''Tuple2@, and so on. As a result, we must check for @''Unit@
-- and @''Tuple<N>@ in 'tupleDegree_maybe' to be thorough. (There is no special
-- tuple syntax for @''Solo@/@'MkSolo@, but we check them here as well for the
-- sake of completeness.)
tupleNameDegree_maybe :: Name -> Maybe Int
tupleNameDegree_maybe :: Name -> Maybe Int
tupleNameDegree_maybe Name
name
  -- First, check for Solo/MkSolo...
#if __GLASGOW_HASKELL__ >= 900
  | Name
name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Solo = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
#if __GLASGOW_HASKELL__ >= 906
  | Name
name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== 'MkSolo = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
#else
  | name == 'Solo = Just 1
#endif
#endif
#if __GLASGOW_HASKELL__ >= 908
  -- ...then, check for Unit...
  | name == ''Unit = Just 0
  -- ...then, check for Tuple<N>. It is theoretically possible for the supplied
  -- Name to be a user-defined data type named Tuple<N>, rather than the actual
  -- tuple types defined in GHC.Tuple. As such, we check that the package and
  -- module for the supplied Name does in fact come from ghc-prim:GHC.Tuple as
  -- a sanity check.
  | -- We use Tuple0 here simply because it is a convenient identifier from
    -- GHC.Tuple. We could just as well use any other identifier from GHC.Tuple,
    -- however.
    namePackage name == namePackage ''Tuple0
  , nameModule name == nameModule ''Tuple0
  , 'T':'u':'p':'l':'e':n <- nameBase name
    -- This relies on the Read Int instance. This is more permissive than what
    -- we need, since there are valid Int strings (e.g., "-1") that do not have
    -- corresponding Tuple<N> names (e.g., "Tuple-1" is not a data type in
    -- GHC.Tuple). As such, we depend on the assumption that the input string
    -- does in fact come from GHC.Tuple, which we check above.
  = readMaybe n
#endif
  -- ...otherwise, fall back on tuple syntax.
  | Bool
otherwise
  = String -> Maybe Int
tuple_syntax_degree_maybe (Name -> String
nameBase Name
name)
  where
    -- Extract the degree of a string using tuple syntax (e.g., @''(,,)@).
    tuple_syntax_degree_maybe :: String -> Maybe Int
    tuple_syntax_degree_maybe :: String -> Maybe Int
tuple_syntax_degree_maybe String
s = do
      Char
'(' : String
s1 <- String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s
      (String
commas, String
")") <- (String, String) -> Maybe (String, String)
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return ((String, String) -> Maybe (String, String))
-> (String, String) -> Maybe (String, String)
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
',') String
s1
      let degree :: Int
degree
            | String
"" <- String
commas = Int
0
            | Bool
otherwise    = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
commas Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
      Int -> Maybe Int
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
degree

-- | Extract the degree of an unboxed sum
unboxedSumDegree_maybe :: String -> Maybe Int
unboxedSumDegree_maybe :: String -> Maybe Int
unboxedSumDegree_maybe = Char -> String -> Maybe Int
unboxedSumTupleDegree_maybe Char
'|'

-- | Extract the degree of an unboxed sum 'Name'.
--
-- In addition to recognizing unboxed sum syntax (e.g., @''(#||#)@), this also
-- recognizes @''Sum<N>#@ (for unboxed <N>-ary sum type constructors). In recent
-- versions of GHC, @''Sum2#@ is a synonym for @''(#|#)@, @''Sum3#@ is a synonym
-- for @''(#||#)@, and so on. As a result, we must check for @''Sum<N>#@ in
-- 'unboxedSumNameDegree_maybe' to be thorough.
unboxedSumNameDegree_maybe :: Name -> Maybe Int
unboxedSumNameDegree_maybe :: Name -> Maybe Int
unboxedSumNameDegree_maybe Name
name
#if __GLASGOW_HASKELL__ >= 910
  -- Check for Sum<N>#. It is theoretically possible for the supplied
  -- Name to be a user-defined data type named Sum<N>#, rather than the actual
  -- unboxed sum types defined in GHC.Types. As such, we check that the package
  -- and module for the supplied Name does in fact come from ghc-prim:GHC.Types
  -- as a sanity check.
  | -- We use Sum2# here simply because it is a convenient identifier from
    -- GHC.Types. We could just as well use any other identifier from GHC.Types,
    -- however.
    namePackage name == namePackage ''Sum2#
  , nameModule name == nameModule ''Sum2#
  , 'S':'u':'m':n:"#" <- nameBase name
    -- This relies on the Read Int instance. This is more permissive than what
    -- we need, since there are valid Int strings (e.g., "-1") that do not have
    -- corresponding Sum<N># names (e.g., "Sum-1#" is not a data type in
    -- GHC.Types). As such, we depend on the assumption that the input string
    -- does in fact come from GHC.Types, which we check above.
  = readMaybe [n]
#endif
  -- ...otherwise, fall back on unboxed sum syntax.
  | Bool
otherwise
  = String -> Maybe Int
unboxedSumDegree_maybe (Name -> String
nameBase Name
name)

-- | Extract the degree of an unboxed tuple
unboxedTupleDegree_maybe :: String -> Maybe Int
unboxedTupleDegree_maybe :: String -> Maybe Int
unboxedTupleDegree_maybe = Char -> String -> Maybe Int
unboxedSumTupleDegree_maybe Char
','

-- | Extract the degree of an unboxed sum or tuple
unboxedSumTupleDegree_maybe :: Char -> String -> Maybe Int
unboxedSumTupleDegree_maybe :: Char -> String -> Maybe Int
unboxedSumTupleDegree_maybe Char
sep String
s = do
  Char
'(' : Char
'#' : String
s1 <- String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s
  (String
seps, String
"#)") <- (String, String) -> Maybe (String, String)
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return ((String, String) -> Maybe (String, String))
-> (String, String) -> Maybe (String, String)
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
sep) String
s1
  let degree :: Int
degree
        | String
"" <- String
seps = Int
0
        | Bool
otherwise  = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
seps Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
  Int -> Maybe Int
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
degree

-- | Extract the degree of an unboxed tuple 'Name'.
--
-- In addition to recognizing unboxed tuple syntax (e.g., @''(#,,#)@), this also
-- recognizes the following:
--
-- * @''Unit#@ (for unboxed 0-tuples)
--
-- * @''Solo#@/@'Solo#@ (for unboxed 1-tuples)
--
-- * @''Tuple<N>#@ (for unboxed <N>-tuples)
--
-- In recent versions of GHC, @''(##)@ is a synonym for @''Unit#@, @''(#,#)@ is
-- a synonym for @''Tuple2#@, and so on. As a result, we must check for
-- @''Unit#@, and @''Tuple<N>@ in 'unboxedTupleNameDegree_maybe' to be thorough.
-- (There is no special unboxed tuple type constructor for @''Solo#@/@'Solo#@,
-- but we check them here as well for the sake of completeness.)
unboxedTupleNameDegree_maybe :: Name -> Maybe Int
unboxedTupleNameDegree_maybe :: Name -> Maybe Int
unboxedTupleNameDegree_maybe Name
name
#if __GLASGOW_HASKELL__ >= 910
  -- First, check for Solo#...
  | name == ''Solo# = Just 1
  -- ...then, check for Unit#...
  | name == ''Unit# = Just 0
  -- ...then, check for Tuple<N>#. It is theoretically possible for the supplied
  -- Name to be a user-defined data type named Tuple<N>#, rather than the actual
  -- unboxed tuple types defined in GHC.Types. As such, we check that the
  -- package and module for the supplied Name does in fact come from
  -- ghc-prim:GHC.Types as a sanity check.
  | -- We use Tuple0# here simply because it is a convenient identifier from
    -- GHC.Types. We could just as well use any other identifier from GHC.Types,
    -- however.
    namePackage name == namePackage ''Tuple0#
  , nameModule name == nameModule ''Tuple0#
  , 'T':'u':'p':'l':'e':n:"#" <- nameBase name
    -- This relies on the Read Int instance. This is more permissive than what
    -- we need, since there are valid Int strings (e.g., "-1") that do not have
    -- corresponding Tuple<N># names (e.g., "Tuple-1#" is not a data type in
    -- GHC.Types). As such, we depend on the assumption that the input string
    -- does in fact come from GHC.Types, which we check above.
  = readMaybe [n]
#endif
  -- ...otherwise, fall back on unboxed tuple syntax.
  | Bool
otherwise
  = String -> Maybe Int
unboxedTupleDegree_maybe (Name -> String
nameBase Name
name)

-- | If the argument is a tuple type, return the components
splitTuple_maybe :: Type -> Maybe [Type]
splitTuple_maybe :: Kind -> Maybe [Kind]
splitTuple_maybe Kind
t = [Kind] -> Kind -> Maybe [Kind]
go [] Kind
t
  where go :: [Kind] -> Kind -> Maybe [Kind]
go [Kind]
args (Kind
t1 `AppT` Kind
t2) = [Kind] -> Kind -> Maybe [Kind]
go (Kind
t2Kind -> [Kind] -> [Kind]
forall a. a -> [a] -> [a]
:[Kind]
args) Kind
t1
        go [Kind]
args (Kind
t1 `SigT` Kind
_k) = [Kind] -> Kind -> Maybe [Kind]
go [Kind]
args Kind
t1
        go [Kind]
args (ConT Name
con_name)
          | Just Int
degree <- Name -> Maybe Int
tupleNameDegree_maybe Name
con_name
          , [Kind] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Kind]
args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
degree
          = [Kind] -> Maybe [Kind]
forall a. a -> Maybe a
Just [Kind]
args
        go [Kind]
args (TupleT Int
degree)
          | [Kind] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Kind]
args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
degree
          = [Kind] -> Maybe [Kind]
forall a. a -> Maybe a
Just [Kind]
args
        go [Kind]
_ Kind
_ = Maybe [Kind]
forall a. Maybe a
Nothing

-- | The type variable binders in a @forall@. This is not used by the TH AST
-- itself, but this is used as an intermediate data type in 'FAForalls'.
data ForallTelescope
  = ForallVis [TyVarBndrUnit]
    -- ^ A visible @forall@ (e.g., @forall a -> {...}@).
    --   These do not have any notion of specificity, so we use
    --   '()' as a placeholder value in the 'TyVarBndr's.
  | ForallInvis [TyVarBndrSpec]
    -- ^ An invisible @forall@ (e.g., @forall a {b} c -> {...}@),
    --   where each binder has a 'Specificity'.
  deriving (ForallTelescope -> ForallTelescope -> Bool
(ForallTelescope -> ForallTelescope -> Bool)
-> (ForallTelescope -> ForallTelescope -> Bool)
-> Eq ForallTelescope
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ForallTelescope -> ForallTelescope -> Bool
== :: ForallTelescope -> ForallTelescope -> Bool
$c/= :: ForallTelescope -> ForallTelescope -> Bool
/= :: ForallTelescope -> ForallTelescope -> Bool
Eq, Int -> ForallTelescope -> String -> String
[ForallTelescope] -> String -> String
ForallTelescope -> String
(Int -> ForallTelescope -> String -> String)
-> (ForallTelescope -> String)
-> ([ForallTelescope] -> String -> String)
-> Show ForallTelescope
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ForallTelescope -> String -> String
showsPrec :: Int -> ForallTelescope -> String -> String
$cshow :: ForallTelescope -> String
show :: ForallTelescope -> String
$cshowList :: [ForallTelescope] -> String -> String
showList :: [ForallTelescope] -> String -> String
Show, Typeable ForallTelescope
Typeable ForallTelescope =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ForallTelescope -> c ForallTelescope)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ForallTelescope)
-> (ForallTelescope -> Constr)
-> (ForallTelescope -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ForallTelescope))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ForallTelescope))
-> ((forall b. Data b => b -> b)
    -> ForallTelescope -> ForallTelescope)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> ForallTelescope -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ForallTelescope -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ForallTelescope -> m ForallTelescope)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ForallTelescope -> m ForallTelescope)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ForallTelescope -> m ForallTelescope)
-> Data ForallTelescope
ForallTelescope -> Constr
ForallTelescope -> DataType
(forall b. Data b => b -> b) -> ForallTelescope -> ForallTelescope
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> ForallTelescope -> u
forall u. (forall d. Data d => d -> u) -> ForallTelescope -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ForallTelescope
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ForallTelescope -> c ForallTelescope
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ForallTelescope)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ForallTelescope)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ForallTelescope -> c ForallTelescope
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ForallTelescope -> c ForallTelescope
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ForallTelescope
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ForallTelescope
$ctoConstr :: ForallTelescope -> Constr
toConstr :: ForallTelescope -> Constr
$cdataTypeOf :: ForallTelescope -> DataType
dataTypeOf :: ForallTelescope -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ForallTelescope)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ForallTelescope)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ForallTelescope)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ForallTelescope)
$cgmapT :: (forall b. Data b => b -> b) -> ForallTelescope -> ForallTelescope
gmapT :: (forall b. Data b => b -> b) -> ForallTelescope -> ForallTelescope
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ForallTelescope -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ForallTelescope -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ForallTelescope -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> ForallTelescope -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> ForallTelescope -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ForallTelescope -> m ForallTelescope
Data)

-- | The list of arguments in a function 'Type'.
data FunArgs
  = FANil
    -- ^ No more arguments.
  | FAForalls ForallTelescope FunArgs
    -- ^ A series of @forall@ed type variables followed by a dot (if
    --   'ForallInvis') or an arrow (if 'ForallVis'). For example,
    --   the type variables @a1 ... an@ in @forall a1 ... an. r@.
  | FACxt Cxt FunArgs
    -- ^ A series of constraint arguments followed by @=>@. For example,
    --   the @(c1, ..., cn)@ in @(c1, ..., cn) => r@.
  | FAAnon Type FunArgs
    -- ^ An anonymous argument followed by an arrow. For example, the @a@
    --   in @a -> r@.
  deriving (FunArgs -> FunArgs -> Bool
(FunArgs -> FunArgs -> Bool)
-> (FunArgs -> FunArgs -> Bool) -> Eq FunArgs
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FunArgs -> FunArgs -> Bool
== :: FunArgs -> FunArgs -> Bool
$c/= :: FunArgs -> FunArgs -> Bool
/= :: FunArgs -> FunArgs -> Bool
Eq, Int -> FunArgs -> String -> String
[FunArgs] -> String -> String
FunArgs -> String
(Int -> FunArgs -> String -> String)
-> (FunArgs -> String)
-> ([FunArgs] -> String -> String)
-> Show FunArgs
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> FunArgs -> String -> String
showsPrec :: Int -> FunArgs -> String -> String
$cshow :: FunArgs -> String
show :: FunArgs -> String
$cshowList :: [FunArgs] -> String -> String
showList :: [FunArgs] -> String -> String
Show, Typeable FunArgs
Typeable FunArgs =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> FunArgs -> c FunArgs)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c FunArgs)
-> (FunArgs -> Constr)
-> (FunArgs -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c FunArgs))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FunArgs))
-> ((forall b. Data b => b -> b) -> FunArgs -> FunArgs)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> FunArgs -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> FunArgs -> r)
-> (forall u. (forall d. Data d => d -> u) -> FunArgs -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> FunArgs -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> FunArgs -> m FunArgs)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> FunArgs -> m FunArgs)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> FunArgs -> m FunArgs)
-> Data FunArgs
FunArgs -> Constr
FunArgs -> DataType
(forall b. Data b => b -> b) -> FunArgs -> FunArgs
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> FunArgs -> u
forall u. (forall d. Data d => d -> u) -> FunArgs -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FunArgs -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FunArgs -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FunArgs
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FunArgs -> c FunArgs
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FunArgs)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FunArgs)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FunArgs -> c FunArgs
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FunArgs -> c FunArgs
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FunArgs
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FunArgs
$ctoConstr :: FunArgs -> Constr
toConstr :: FunArgs -> Constr
$cdataTypeOf :: FunArgs -> DataType
dataTypeOf :: FunArgs -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FunArgs)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FunArgs)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FunArgs)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c FunArgs)
$cgmapT :: (forall b. Data b => b -> b) -> FunArgs -> FunArgs
gmapT :: (forall b. Data b => b -> b) -> FunArgs -> FunArgs
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FunArgs -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FunArgs -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FunArgs -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FunArgs -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> FunArgs -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> FunArgs -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FunArgs -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FunArgs -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FunArgs -> m FunArgs
Data)

-- | A /visible/ function argument type (i.e., one that must be supplied
-- explicitly in the source code). This is in contrast to /invisible/
-- arguments (e.g., the @c@ in @c => r@), which are instantiated without
-- the need for explicit user input.
data VisFunArg
  = VisFADep TyVarBndrUnit
    -- ^ A visible @forall@ (e.g., @forall a -> a@).
  | VisFAAnon Type
    -- ^ An anonymous argument followed by an arrow (e.g., @a -> r@).
  deriving (VisFunArg -> VisFunArg -> Bool
(VisFunArg -> VisFunArg -> Bool)
-> (VisFunArg -> VisFunArg -> Bool) -> Eq VisFunArg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VisFunArg -> VisFunArg -> Bool
== :: VisFunArg -> VisFunArg -> Bool
$c/= :: VisFunArg -> VisFunArg -> Bool
/= :: VisFunArg -> VisFunArg -> Bool
Eq, Int -> VisFunArg -> String -> String
[VisFunArg] -> String -> String
VisFunArg -> String
(Int -> VisFunArg -> String -> String)
-> (VisFunArg -> String)
-> ([VisFunArg] -> String -> String)
-> Show VisFunArg
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> VisFunArg -> String -> String
showsPrec :: Int -> VisFunArg -> String -> String
$cshow :: VisFunArg -> String
show :: VisFunArg -> String
$cshowList :: [VisFunArg] -> String -> String
showList :: [VisFunArg] -> String -> String
Show, Typeable VisFunArg
Typeable VisFunArg =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> VisFunArg -> c VisFunArg)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c VisFunArg)
-> (VisFunArg -> Constr)
-> (VisFunArg -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c VisFunArg))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c VisFunArg))
-> ((forall b. Data b => b -> b) -> VisFunArg -> VisFunArg)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> VisFunArg -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> VisFunArg -> r)
-> (forall u. (forall d. Data d => d -> u) -> VisFunArg -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> VisFunArg -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg)
-> Data VisFunArg
VisFunArg -> Constr
VisFunArg -> DataType
(forall b. Data b => b -> b) -> VisFunArg -> VisFunArg
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> VisFunArg -> u
forall u. (forall d. Data d => d -> u) -> VisFunArg -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> VisFunArg -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> VisFunArg -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c VisFunArg
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> VisFunArg -> c VisFunArg
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c VisFunArg)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c VisFunArg)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> VisFunArg -> c VisFunArg
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> VisFunArg -> c VisFunArg
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c VisFunArg
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c VisFunArg
$ctoConstr :: VisFunArg -> Constr
toConstr :: VisFunArg -> Constr
$cdataTypeOf :: VisFunArg -> DataType
dataTypeOf :: VisFunArg -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c VisFunArg)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c VisFunArg)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c VisFunArg)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c VisFunArg)
$cgmapT :: (forall b. Data b => b -> b) -> VisFunArg -> VisFunArg
gmapT :: (forall b. Data b => b -> b) -> VisFunArg -> VisFunArg
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> VisFunArg -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> VisFunArg -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> VisFunArg -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> VisFunArg -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> VisFunArg -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> VisFunArg -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> VisFunArg -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> VisFunArg -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> VisFunArg -> m VisFunArg
Data)

-- | Filter the visible function arguments from a list of 'FunArgs'.
filterVisFunArgs :: FunArgs -> [VisFunArg]
filterVisFunArgs :: FunArgs -> [VisFunArg]
filterVisFunArgs FunArgs
FANil = []
filterVisFunArgs (FAForalls ForallTelescope
tele FunArgs
args) =
  case ForallTelescope
tele of
    ForallVis [TyVarBndrUnit]
tvbs -> (TyVarBndrUnit -> VisFunArg) -> [TyVarBndrUnit] -> [VisFunArg]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBndrUnit -> VisFunArg
VisFADep [TyVarBndrUnit]
tvbs [VisFunArg] -> [VisFunArg] -> [VisFunArg]
forall a. [a] -> [a] -> [a]
++ [VisFunArg]
args'
    ForallInvis [TyVarBndrSpec]
_  -> [VisFunArg]
args'
  where
    args' :: [VisFunArg]
args' = FunArgs -> [VisFunArg]
filterVisFunArgs FunArgs
args
filterVisFunArgs (FACxt [Kind]
_ FunArgs
args) =
  FunArgs -> [VisFunArg]
filterVisFunArgs FunArgs
args
filterVisFunArgs (FAAnon Kind
t FunArgs
args) =
  Kind -> VisFunArg
VisFAAnon Kind
tVisFunArg -> [VisFunArg] -> [VisFunArg]
forall a. a -> [a] -> [a]
:FunArgs -> [VisFunArg]
filterVisFunArgs FunArgs
args

-- | Reconstruct an arrow 'Type' from its argument and result types.
ravelType :: FunArgs -> Type -> Type
ravelType :: FunArgs -> Kind -> Kind
ravelType FunArgs
FANil Kind
res = Kind
res
-- We need a special case for FAForalls ForallInvis followed by FACxt so that we may
-- collapse them into a single ForallT when raveling.
-- See Note [Desugaring and sweetening ForallT] in L.H.T.Desugar.Core.
ravelType (FAForalls (ForallInvis [TyVarBndrSpec]
tvbs) (FACxt [Kind]
p FunArgs
args)) Kind
res =
  [TyVarBndrSpec] -> [Kind] -> Kind -> Kind
ForallT [TyVarBndrSpec]
tvbs [Kind]
p (FunArgs -> Kind -> Kind
ravelType FunArgs
args Kind
res)
ravelType (FAForalls (ForallInvis  [TyVarBndrSpec]
tvbs)  FunArgs
args)  Kind
res = [TyVarBndrSpec] -> [Kind] -> Kind -> Kind
ForallT [TyVarBndrSpec]
tvbs [] (FunArgs -> Kind -> Kind
ravelType FunArgs
args Kind
res)
ravelType (FAForalls (ForallVis   [TyVarBndrUnit]
_tvbs) FunArgs
_args) Kind
_res =
#if __GLASGOW_HASKELL__ >= 809
      [TyVarBndrUnit] -> Kind -> Kind
ForallVisT [TyVarBndrUnit]
_tvbs (FunArgs -> Kind -> Kind
ravelType FunArgs
_args Kind
_res)
#else
      error "Visible dependent quantification supported only on GHC 8.10+"
#endif
ravelType (FACxt [Kind]
cxt FunArgs
args) Kind
res = [TyVarBndrSpec] -> [Kind] -> Kind -> Kind
ForallT [] [Kind]
cxt (FunArgs -> Kind -> Kind
ravelType FunArgs
args Kind
res)
ravelType (FAAnon Kind
t FunArgs
args)  Kind
res = Kind -> Kind -> Kind
AppT (Kind -> Kind -> Kind
AppT Kind
ArrowT Kind
t) (FunArgs -> Kind -> Kind
ravelType FunArgs
args Kind
res)

-- | Decompose a function 'Type' into its arguments (the 'FunArgs') and its
-- result type (the 'Type).
unravelType :: Type -> (FunArgs, Type)
unravelType :: Kind -> (FunArgs, Kind)
unravelType (ForallT [TyVarBndrSpec]
tvbs [Kind]
cxt Kind
ty) =
  let (FunArgs
args, Kind
res) = Kind -> (FunArgs, Kind)
unravelType Kind
ty in
  (ForallTelescope -> FunArgs -> FunArgs
FAForalls ([TyVarBndrSpec] -> ForallTelescope
ForallInvis [TyVarBndrSpec]
tvbs) ([Kind] -> FunArgs -> FunArgs
FACxt [Kind]
cxt FunArgs
args), Kind
res)
unravelType (AppT (AppT Kind
ArrowT Kind
t1) Kind
t2) =
  let (FunArgs
args, Kind
res) = Kind -> (FunArgs, Kind)
unravelType Kind
t2 in
  (Kind -> FunArgs -> FunArgs
FAAnon Kind
t1 FunArgs
args, Kind
res)
#if __GLASGOW_HASKELL__ >= 809
unravelType (ForallVisT [TyVarBndrUnit]
tvbs Kind
ty) =
  let (FunArgs
args, Kind
res) = Kind -> (FunArgs, Kind)
unravelType Kind
ty in
  (ForallTelescope -> FunArgs -> FunArgs
FAForalls ([TyVarBndrUnit] -> ForallTelescope
ForallVis [TyVarBndrUnit]
tvbs) FunArgs
args, Kind
res)
#endif
unravelType Kind
t = (FunArgs
FANil, Kind
t)

-- | Remove all of the explicit kind signatures from a 'Type'.
unSigType :: Type -> Type
unSigType :: Kind -> Kind
unSigType (SigT Kind
t Kind
_) = Kind
t
unSigType (AppT Kind
f Kind
x) = Kind -> Kind -> Kind
AppT (Kind -> Kind
unSigType Kind
f) (Kind -> Kind
unSigType Kind
x)
unSigType (ForallT [TyVarBndrSpec]
tvbs [Kind]
ctxt Kind
t) =
  [TyVarBndrSpec] -> [Kind] -> Kind -> Kind
ForallT [TyVarBndrSpec]
tvbs ((Kind -> Kind) -> [Kind] -> [Kind]
forall a b. (a -> b) -> [a] -> [b]
map Kind -> Kind
unSigPred [Kind]
ctxt) (Kind -> Kind
unSigType Kind
t)
unSigType (InfixT Kind
t1 Name
n Kind
t2)  = Kind -> Name -> Kind -> Kind
InfixT (Kind -> Kind
unSigType Kind
t1) Name
n (Kind -> Kind
unSigType Kind
t2)
unSigType (UInfixT Kind
t1 Name
n Kind
t2) = Kind -> Name -> Kind -> Kind
UInfixT (Kind -> Kind
unSigType Kind
t1) Name
n (Kind -> Kind
unSigType Kind
t2)
unSigType (ParensT Kind
t)       = Kind -> Kind
ParensT (Kind -> Kind
unSigType Kind
t)
#if __GLASGOW_HASKELL__ >= 807
unSigType (AppKindT Kind
t Kind
k)       = Kind -> Kind -> Kind
AppKindT (Kind -> Kind
unSigType Kind
t) (Kind -> Kind
unSigType Kind
k)
unSigType (ImplicitParamT String
n Kind
t) = String -> Kind -> Kind
ImplicitParamT String
n (Kind -> Kind
unSigType Kind
t)
#endif
unSigType Kind
t = Kind
t

-- | Remove all of the explicit kind signatures from a 'Pred'.
unSigPred :: Pred -> Pred
unSigPred :: Kind -> Kind
unSigPred = Kind -> Kind
unSigType

-- | Decompose an applied type into its individual components. For example, this:
--
-- @
-- Proxy \@Type Char
-- @
--
-- would be unfolded to this:
--
-- @
-- ('ConT' ''Proxy, ['TyArg' ('ConT' ''Type), 'TANormal' ('ConT' ''Char)])
-- @
--
-- This process forgets about infix application, so both of these types:
--
-- @
-- Int :++: Int
-- (:++:) Int Int
-- @
--
-- will be unfolded to this:
--
-- @
-- ('ConT' ''(:+:), ['TANormal' ('ConT' ''Int), 'TANormal' ('ConT' ''Int)])
-- @
--
-- This function should only be used after all 'UInfixT' and 'PromotedUInfixT'
-- types have been resolved (e.g., via @th-abstraction@'s
-- @<https://hackage.haskell.org/package/th-abstraction-0.5.0.0/docs/Language-Haskell-TH-Datatype.html#v:resolveInfixT resolveInfixT>@
-- function).
unfoldType :: Type -> (Type, [TypeArg])
unfoldType :: Kind -> (Kind, [TypeArg])
unfoldType = [TypeArg] -> Kind -> (Kind, [TypeArg])
go []
  where
    go :: [TypeArg] -> Type -> (Type, [TypeArg])
    go :: [TypeArg] -> Kind -> (Kind, [TypeArg])
go [TypeArg]
acc (ForallT [TyVarBndrSpec]
_ [Kind]
_ Kind
ty)           = [TypeArg] -> Kind -> (Kind, [TypeArg])
go [TypeArg]
acc Kind
ty
    go [TypeArg]
acc (AppT Kind
ty1 Kind
ty2)             = [TypeArg] -> Kind -> (Kind, [TypeArg])
go (Kind -> TypeArg
TANormal Kind
ty2TypeArg -> [TypeArg] -> [TypeArg]
forall a. a -> [a] -> [a]
:[TypeArg]
acc) Kind
ty1
    go [TypeArg]
acc (SigT Kind
ty Kind
_)                = [TypeArg] -> Kind -> (Kind, [TypeArg])
go [TypeArg]
acc Kind
ty
    go [TypeArg]
acc (ParensT Kind
ty)               = [TypeArg] -> Kind -> (Kind, [TypeArg])
go [TypeArg]
acc Kind
ty
    go [TypeArg]
acc (InfixT Kind
ty1 Name
n Kind
ty2)         = [TypeArg] -> Kind -> (Kind, [TypeArg])
go (Kind -> TypeArg
TANormal Kind
ty1TypeArg -> [TypeArg] -> [TypeArg]
forall a. a -> [a] -> [a]
:Kind -> TypeArg
TANormal Kind
ty2TypeArg -> [TypeArg] -> [TypeArg]
forall a. a -> [a] -> [a]
:[TypeArg]
acc) (Name -> Kind
ConT Name
n)
#if __GLASGOW_HASKELL__ >= 807
    go [TypeArg]
acc (AppKindT Kind
ty Kind
ki)           = [TypeArg] -> Kind -> (Kind, [TypeArg])
go (Kind -> TypeArg
TyArg Kind
kiTypeArg -> [TypeArg] -> [TypeArg]
forall a. a -> [a] -> [a]
:[TypeArg]
acc) Kind
ty
#endif
#if __GLASGOW_HASKELL__ >= 904
    go [TypeArg]
acc (PromotedInfixT Kind
ty1 Name
n Kind
ty2) = [TypeArg] -> Kind -> (Kind, [TypeArg])
go (Kind -> TypeArg
TANormal Kind
ty1TypeArg -> [TypeArg] -> [TypeArg]
forall a. a -> [a] -> [a]
:Kind -> TypeArg
TANormal Kind
ty2TypeArg -> [TypeArg] -> [TypeArg]
forall a. a -> [a] -> [a]
:[TypeArg]
acc) (Name -> Kind
PromotedT Name
n)
#endif
    go [TypeArg]
acc Kind
ty                         = (Kind
ty, [TypeArg]
acc)

-- | An argument to a type, either a normal type ('TANormal') or a visible
-- kind application ('TyArg').
--
-- 'TypeArg' is useful when decomposing an application of a 'Type' to its
-- arguments (e.g., in 'unfoldType').
data TypeArg
  = TANormal Type
  | TyArg Kind
  deriving (TypeArg -> TypeArg -> Bool
(TypeArg -> TypeArg -> Bool)
-> (TypeArg -> TypeArg -> Bool) -> Eq TypeArg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TypeArg -> TypeArg -> Bool
== :: TypeArg -> TypeArg -> Bool
$c/= :: TypeArg -> TypeArg -> Bool
/= :: TypeArg -> TypeArg -> Bool
Eq, Int -> TypeArg -> String -> String
[TypeArg] -> String -> String
TypeArg -> String
(Int -> TypeArg -> String -> String)
-> (TypeArg -> String)
-> ([TypeArg] -> String -> String)
-> Show TypeArg
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> TypeArg -> String -> String
showsPrec :: Int -> TypeArg -> String -> String
$cshow :: TypeArg -> String
show :: TypeArg -> String
$cshowList :: [TypeArg] -> String -> String
showList :: [TypeArg] -> String -> String
Show, Typeable TypeArg
Typeable TypeArg =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> TypeArg -> c TypeArg)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TypeArg)
-> (TypeArg -> Constr)
-> (TypeArg -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TypeArg))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeArg))
-> ((forall b. Data b => b -> b) -> TypeArg -> TypeArg)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeArg -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TypeArg -> r)
-> (forall u. (forall d. Data d => d -> u) -> TypeArg -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> TypeArg -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TypeArg -> m TypeArg)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeArg -> m TypeArg)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TypeArg -> m TypeArg)
-> Data TypeArg
TypeArg -> Constr
TypeArg -> DataType
(forall b. Data b => b -> b) -> TypeArg -> TypeArg
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> TypeArg -> u
forall u. (forall d. Data d => d -> u) -> TypeArg -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TypeArg -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TypeArg -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TypeArg
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TypeArg -> c TypeArg
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TypeArg)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeArg)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TypeArg -> c TypeArg
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TypeArg -> c TypeArg
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TypeArg
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TypeArg
$ctoConstr :: TypeArg -> Constr
toConstr :: TypeArg -> Constr
$cdataTypeOf :: TypeArg -> DataType
dataTypeOf :: TypeArg -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TypeArg)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TypeArg)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeArg)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TypeArg)
$cgmapT :: (forall b. Data b => b -> b) -> TypeArg -> TypeArg
gmapT :: (forall b. Data b => b -> b) -> TypeArg -> TypeArg
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TypeArg -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TypeArg -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TypeArg -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TypeArg -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> TypeArg -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> TypeArg -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TypeArg -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TypeArg -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TypeArg -> m TypeArg
Data)

-- | Apply one 'Type' to a list of arguments.
applyType :: Type -> [TypeArg] -> Type
applyType :: Kind -> [TypeArg] -> Kind
applyType = (Kind -> TypeArg -> Kind) -> Kind -> [TypeArg] -> Kind
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Kind -> TypeArg -> Kind
apply
  where
    apply :: Type -> TypeArg -> Type
    apply :: Kind -> TypeArg -> Kind
apply Kind
f (TANormal Kind
x) = Kind
f Kind -> Kind -> Kind
`AppT` Kind
x
    apply Kind
f (TyArg Kind
_x)   =
#if __GLASGOW_HASKELL__ >= 807
                           Kind
f Kind -> Kind -> Kind
`AppKindT` Kind
_x
#else
                           -- VKA isn't supported, so
                           -- conservatively drop the argument
                           f
#endif

-- | Filter the normal type arguments from a list of 'TypeArg's.
filterTANormals :: [TypeArg] -> [Type]
filterTANormals :: [TypeArg] -> [Kind]
filterTANormals = (TypeArg -> Maybe Kind) -> [TypeArg] -> [Kind]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe TypeArg -> Maybe Kind
getTANormal
  where
    getTANormal :: TypeArg -> Maybe Type
    getTANormal :: TypeArg -> Maybe Kind
getTANormal (TANormal Kind
t) = Kind -> Maybe Kind
forall a. a -> Maybe a
Just Kind
t
    getTANormal (TyArg {})   = Maybe Kind
forall a. Maybe a
Nothing

-- | Convert a 'TyVarBndrVis' to a 'TypeArg'. That is, convert a binder with a
-- 'BndrReq' visibility to a 'TANormal' and a binder with 'BndrInvis'
-- visibility to a 'TyArg'.
--
-- If given a 'KindedTV', the resulting 'TypeArg' will omit the kind signature.
-- Use 'tyVarBndrVisToTypeArgWithSig' if you want to preserve the kind
-- signature.
tyVarBndrVisToTypeArg :: TyVarBndrVis -> TypeArg
tyVarBndrVisToTypeArg :: TyVarBndrUnit -> TypeArg
tyVarBndrVisToTypeArg TyVarBndrUnit
bndr =
  case TyVarBndrUnit -> ()
forall flag. TyVarBndr_ flag -> flag
tvFlag TyVarBndrUnit
bndr of
    ()
BndrReq   -> Kind -> TypeArg
TANormal Kind
bndr_ty
    ()
BndrInvis -> Kind -> TypeArg
TyArg Kind
bndr_ty
  where
    bndr_ty :: Kind
bndr_ty = TyVarBndrUnit -> Kind
forall flag. TyVarBndr_ flag -> Kind
tvbToType TyVarBndrUnit
bndr

-- | Convert a 'TyVarBndrVis' to a 'TypeArg'. That is, convert a binder with a
-- 'BndrReq' visibility to a 'TANormal' and a binder with 'BndrInvis'
-- visibility to a 'TyArg'.
--
-- If given a 'KindedTV', the resulting 'TypeArg' will preserve the kind
-- signature. Use 'tyVarBndrVisToTypeArg' if you want to omit the kind
-- signature.
tyVarBndrVisToTypeArgWithSig :: TyVarBndrVis -> TypeArg
tyVarBndrVisToTypeArgWithSig :: TyVarBndrUnit -> TypeArg
tyVarBndrVisToTypeArgWithSig TyVarBndrUnit
bndr =
  case TyVarBndrUnit -> ()
forall flag. TyVarBndr_ flag -> flag
tvFlag TyVarBndrUnit
bndr of
    ()
BndrReq   -> Kind -> TypeArg
TANormal Kind
bndr_ty
    ()
BndrInvis -> Kind -> TypeArg
TyArg Kind
bndr_ty
  where
    bndr_ty :: Kind
bndr_ty = TyVarBndrUnit -> Kind
forall flag. TyVarBndr_ flag -> Kind
tvbToTypeWithSig TyVarBndrUnit
bndr

-- | Extract the underlying 'Type' or 'Kind' from a 'TypeArg'. This forgets
-- information about whether a type is a normal argument or not, so use with
-- caution.
probablyWrongUnTypeArg :: TypeArg -> Type
probablyWrongUnTypeArg :: TypeArg -> Kind
probablyWrongUnTypeArg (TANormal Kind
t) = Kind
t
probablyWrongUnTypeArg (TyArg Kind
k)    = Kind
k

-------------------------------------------------------------------------------
-- Matching standalone kind signatures with binders in type-level declarations
-------------------------------------------------------------------------------

-- @'matchUpSAKWithDecl' decl_sak decl_bndrs@ produces @TyVarBndr'
-- 'ForAllTyFlag'@s for a declaration, using the original declaration's
-- standalone kind signature (@decl_sak@) and its user-written binders
-- (@decl_bndrs@) as a template. For this example:
--
-- @
-- type D :: forall j k. k -> j -> Type
-- data D \@j \@l (a :: l) b = ...
-- @
--
-- We would produce the following @'TyVarBndr' 'ForAllTyFlag'@s:
--
-- @
-- \@j \@l (a :: l) (b :: j)
-- @
--
-- From here, these @'TyVarBndr' 'ForAllTyFlag'@s can be converted into other
-- forms of 'TyVarBndr's:
--
-- * They can be converted to 'TyVarBndrSpec's using 'tvbForAllTyFlagsToSpecs'.
--
-- * They can be converted to 'TyVarBndrVis'es using 'tvbForAllTyFlagsToVis'.
--
-- Note that:
--
-- * This function has a precondition that the length of @decl_bndrs@ must
--   always be equal to the number of visible quantifiers (i.e., the number of
--   function arrows plus the number of visible @forall@–bound variables) in
--   @decl_sak@.
--
-- * Whenever possible, this function reuses type variable names from the
--   declaration's user-written binders. This is why the @'TyVarBndr'
--   'ForAllTyFlag'@ use @\@j \@l@ instead of @\@j \@k@, since the @(a :: l)@
--   binder uses @l@ instead of @k@. We could have just as well chose the other
--   way around, but we chose to pick variable names from the user-written
--   binders since they scope over other parts of the declaration. (For example,
--   the user-written binders of a @data@ declaration scope over the type
--   variables mentioned in a @deriving@ clause.) As such, keeping these names
--   avoids having to perform some alpha-renaming.
--
-- This function's implementation was heavily inspired by parts of GHC's
-- kcCheckDeclHeader_sig function:
-- https://gitlab.haskell.org/ghc/ghc/-/blob/1464a2a8de082f66ae250d63ab9d94dbe2ef8620/compiler/GHC/Tc/Gen/HsType.hs#L2524-2643
matchUpSAKWithDecl ::
     forall q.
     Fail.MonadFail q
  => Kind
     -- ^ The declaration's standalone kind signature
  -> [TyVarBndrVis]
     -- ^ The user-written binders in the declaration
  -> q [TyVarBndr_ ForAllTyFlag]
matchUpSAKWithDecl :: forall (q :: * -> *).
MonadFail q =>
Kind -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
matchUpSAKWithDecl Kind
decl_sak [TyVarBndrUnit]
decl_bndrs = do
  -- (1) First, explicitly quantify any free kind variables in `decl_sak` using
  -- an invisible @forall@. This is done to ensure that precondition (2) in
  -- `matchUpSigWithDecl` is upheld. (See the Haddocks for that function).
  let decl_sak_free_tvbs :: [TyVarBndrSpec]
decl_sak_free_tvbs =
        Specificity -> [TyVarBndrUnit] -> [TyVarBndrSpec]
forall newFlag oldFlag.
newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
changeTVFlags Specificity
SpecifiedSpec ([TyVarBndrUnit] -> [TyVarBndrSpec])
-> [TyVarBndrUnit] -> [TyVarBndrSpec]
forall a b. (a -> b) -> a -> b
$ [Kind] -> [TyVarBndrUnit]
freeVariablesWellScoped [Kind
decl_sak]
      decl_sak' :: Kind
decl_sak' = [TyVarBndrSpec] -> [Kind] -> Kind -> Kind
ForallT [TyVarBndrSpec]
decl_sak_free_tvbs [] Kind
decl_sak

  -- (2) Next, compute type variable binders using `matchUpSigWithDecl`. Note
  -- that these can be biased towards type variable names mention in `decl_sak`
  -- over names mentioned in `decl_bndrs`, but we will fix that up in the next
  -- step.
  let (FunArgs
decl_sak_args, Kind
_) = Kind -> (FunArgs, Kind)
unravelType Kind
decl_sak'
  [TyVarBndr_ ForAllTyFlag]
sing_sak_tvbs <- FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
forall (q :: * -> *).
MonadFail q =>
FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
matchUpSigWithDecl FunArgs
decl_sak_args [TyVarBndrUnit]
decl_bndrs

  -- (3) Finally, swizzle the type variable names so that names in `decl_bndrs`
  -- are preferred over names in `decl_sak`.
  --
  -- This is heavily inspired by similar code in GHC:
  -- https://gitlab.haskell.org/ghc/ghc/-/blob/cec903899234bf9e25ea404477ba846ac1e963bb/compiler/GHC/Tc/Gen/HsType.hs#L2607-2616
  let invis_decl_sak_args :: [TyVarBndrSpec]
invis_decl_sak_args = FunArgs -> [TyVarBndrSpec]
filterInvisTvbArgs FunArgs
decl_sak_args
      invis_decl_sak_arg_nms :: [Name]
invis_decl_sak_arg_nms = (TyVarBndrSpec -> Name) -> [TyVarBndrSpec] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBndrSpec -> Name
forall flag. TyVarBndr_ flag -> Name
tvName [TyVarBndrSpec]
invis_decl_sak_args

      invis_decl_bndrs :: [TyVarBndrUnit]
invis_decl_bndrs = [TyVarBndrUnit] -> [TyVarBndrUnit]
forall flag. [TyVarBndr_ flag] -> [TyVarBndrUnit]
freeKindVariablesWellScoped [TyVarBndrUnit]
decl_bndrs
      invis_decl_bndr_nms :: [Name]
invis_decl_bndr_nms = (TyVarBndrUnit -> Name) -> [TyVarBndrUnit] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBndrUnit -> Name
forall flag. TyVarBndr_ flag -> Name
tvName [TyVarBndrUnit]
invis_decl_bndrs

      swizzle_env :: Map Name Name
swizzle_env =
        [(Name, Name)] -> Map Name Name
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Name, Name)] -> Map Name Name)
-> [(Name, Name)] -> Map Name Name
forall a b. (a -> b) -> a -> b
$ [Name] -> [Name] -> [(Name, Name)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
invis_decl_sak_arg_nms [Name]
invis_decl_bndr_nms
      (Map Name Kind
_, [TyVarBndr_ ForAllTyFlag]
swizzled_sing_sak_tvbs) =
        (Map Name Kind
 -> TyVarBndr_ ForAllTyFlag
 -> (Map Name Kind, TyVarBndr_ ForAllTyFlag))
-> Map Name Kind
-> [TyVarBndr_ ForAllTyFlag]
-> (Map Name Kind, [TyVarBndr_ ForAllTyFlag])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL (Map Name Name
-> Map Name Kind
-> TyVarBndr_ ForAllTyFlag
-> (Map Name Kind, TyVarBndr_ ForAllTyFlag)
forall flag.
Map Name Name
-> Map Name Kind
-> TyVarBndr_ flag
-> (Map Name Kind, TyVarBndr_ flag)
swizzleTvb Map Name Name
swizzle_env) Map Name Kind
forall k a. Map k a
Map.empty [TyVarBndr_ ForAllTyFlag]
sing_sak_tvbs
  [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a. a -> q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [TyVarBndr_ ForAllTyFlag]
swizzled_sing_sak_tvbs

-- Match the quantifiers in a type-level declaration's standalone kind signature
-- with the user-written binders in the declaration. This function assumes the
-- following preconditions:
--
-- 1. The number of required binders in the declaration's user-written binders
--    is equal to the number of visible quantifiers (i.e., the number of
--    function arrows plus the number of visible @forall@–bound variables) in
--    the standalone kind signature.
--
-- 2. The number of invisible \@-binders in the declaration's user-written
--    binders is less than or equal to the number of invisible quantifiers
--    (i.e., the number of invisible @forall@–bound variables) in the
--    standalone kind signature.
--
-- The implementation of this function is heavily based on a GHC function of
-- the same name:
-- https://gitlab.haskell.org/ghc/ghc/-/blob/1464a2a8de082f66ae250d63ab9d94dbe2ef8620/compiler/GHC/Tc/Gen/HsType.hs#L2645-2715
matchUpSigWithDecl ::
     forall q.
     Fail.MonadFail q
  => FunArgs
     -- ^ The quantifiers in the declaration's standalone kind signature
  -> [TyVarBndrVis]
     -- ^ The user-written binders in the declaration
  -> q [TyVarBndr_ ForAllTyFlag]
matchUpSigWithDecl :: forall (q :: * -> *).
MonadFail q =>
FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
matchUpSigWithDecl = Map Name Kind
-> FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
go_fun_args Map Name Kind
forall k a. Map k a
Map.empty
  where
    go_fun_args ::
         Map Name Type
         -- ^ A substitution from the names of @forall@-bound variables in the
         -- standalone kind signature to corresponding binder names in the
         -- user-written binders. This is because we want to reuse type variable
         -- names from the user-written binders whenever possible. For example:
         --
         -- @
         -- type T :: forall a. forall b -> Maybe (a, b) -> Type
         -- data T @x y z
         -- @
         --
         -- After matching up the @a@ in @forall a.@ with @x@ and
         -- the @b@ in @forall b ->@ with @y@, this substitution will be
         -- extended with @[a :-> x, b :-> y]@. This ensures that we will
         -- produce @Maybe (x, y)@ instead of @Maybe (a, b)@ in
         -- the kind for @z@.
      -> FunArgs -> [TyVarBndrVis] -> q [TyVarBndr_ ForAllTyFlag]
    go_fun_args :: Map Name Kind
-> FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
go_fun_args Map Name Kind
_ FunArgs
FANil [] =
      [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a. a -> q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    -- This should not happen, per precondition (1).
    go_fun_args Map Name Kind
_ FunArgs
FANil [TyVarBndrUnit]
decl_bndrs =
      String -> q [TyVarBndr_ ForAllTyFlag]
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> q [TyVarBndr_ ForAllTyFlag])
-> String -> q [TyVarBndr_ ForAllTyFlag]
forall a b. (a -> b) -> a -> b
$ String
"matchUpSigWithDecl.go_fun_args: Too many binders: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [TyVarBndrUnit] -> String
forall a. Show a => a -> String
show [TyVarBndrUnit]
decl_bndrs
    -- GHC now disallows kind-level constraints, per this GHC proposal:
    -- https://github.com/ghc-proposals/ghc-proposals/blob/b0687d96ce8007294173b7f628042ac4260cc738/proposals/0547-no-kind-equalities.rst
    -- As such, we reject non-empty kind contexts. Empty contexts (which are
    -- benign) can sometimes arise due to @ForallT@, so we add a special case
    -- to allow them.
    go_fun_args Map Name Kind
subst (FACxt [] FunArgs
args) [TyVarBndrUnit]
decl_bndrs =
      Map Name Kind
-> FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
go_fun_args Map Name Kind
subst FunArgs
args [TyVarBndrUnit]
decl_bndrs
    go_fun_args Map Name Kind
_ (FACxt (Kind
_:[Kind]
_) FunArgs
_) [TyVarBndrUnit]
_ =
      String -> q [TyVarBndr_ ForAllTyFlag]
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"matchUpSigWithDecl.go_fun_args: Unexpected kind-level constraint"
    go_fun_args Map Name Kind
subst (FAForalls (ForallInvis [TyVarBndrSpec]
tvbs) FunArgs
sig_args) [TyVarBndrUnit]
decl_bndrs =
      Map Name Kind
-> [TyVarBndrSpec]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_invis_tvbs Map Name Kind
subst [TyVarBndrSpec]
tvbs FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
    go_fun_args Map Name Kind
subst (FAForalls (ForallVis [TyVarBndrUnit]
tvbs) FunArgs
sig_args) [TyVarBndrUnit]
decl_bndrs =
      Map Name Kind
-> [TyVarBndrUnit]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_vis_tvbs Map Name Kind
subst [TyVarBndrUnit]
tvbs FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
    go_fun_args Map Name Kind
subst (FAAnon Kind
anon FunArgs
sig_args) (TyVarBndrUnit
decl_bndr:[TyVarBndrUnit]
decl_bndrs) =
      case TyVarBndrUnit -> ()
forall flag. TyVarBndr_ flag -> flag
tvFlag TyVarBndrUnit
decl_bndr of
        -- If the next decl_bndr is required, then we must match its kind (if
        -- one is provided) against the anonymous kind argument.
        ()
BndrReq -> do
          let decl_bndr_name :: Name
decl_bndr_name = TyVarBndrUnit -> Name
forall flag. TyVarBndr_ flag -> Name
tvName TyVarBndrUnit
decl_bndr
              mb_decl_bndr_kind :: Maybe Kind
mb_decl_bndr_kind = TyVarBndrUnit -> Maybe Kind
forall flag. TyVarBndr_ flag -> Maybe Kind
extractTvbKind_maybe TyVarBndrUnit
decl_bndr
              anon' :: Kind
anon' = Map Name Kind -> Kind -> Kind
forall a. TypeSubstitution a => Map Name Kind -> a -> a
applySubstitution Map Name Kind
subst Kind
anon

              anon'' :: Kind
anon'' =
                case Maybe Kind
mb_decl_bndr_kind of
                  Maybe Kind
Nothing -> Kind
anon'
                  Just Kind
decl_bndr_kind -> do
                    let mb_match_subst :: Maybe (Map Name Kind)
mb_match_subst = Kind -> Kind -> Maybe (Map Name Kind)
matchTy Kind
decl_bndr_kind Kind
anon'
                    Kind -> (Map Name Kind -> Kind) -> Maybe (Map Name Kind) -> Kind
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Kind
decl_bndr_kind (Map Name Kind -> Kind -> Kind
forall a. TypeSubstitution a => Map Name Kind -> a -> a
`applySubstitution` Kind
decl_bndr_kind) Maybe (Map Name Kind)
mb_match_subst
          [TyVarBndr_ ForAllTyFlag]
sig_args' <- Map Name Kind
-> FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
go_fun_args Map Name Kind
subst FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
          [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a. a -> q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag])
-> [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a b. (a -> b) -> a -> b
$ Name -> ForAllTyFlag -> Kind -> TyVarBndr_ ForAllTyFlag
forall flag. Name -> flag -> Kind -> TyVarBndr_ flag
kindedTVFlag Name
decl_bndr_name ForAllTyFlag
Required Kind
anon'' TyVarBndr_ ForAllTyFlag
-> [TyVarBndr_ ForAllTyFlag] -> [TyVarBndr_ ForAllTyFlag]
forall a. a -> [a] -> [a]
: [TyVarBndr_ ForAllTyFlag]
sig_args'
        -- We have a visible, anonymous argument in the kind, but an invisible
        -- @-binder as the next decl_bndr. This is ill kinded, so throw an
        -- error.
        --
        -- This should not happen, per precondition (2).
        ()
BndrInvis ->
          String -> q [TyVarBndr_ ForAllTyFlag]
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> q [TyVarBndr_ ForAllTyFlag])
-> String -> q [TyVarBndr_ ForAllTyFlag]
forall a b. (a -> b) -> a -> b
$ String
"dMatchUpSigWithDecl.go_fun_args: Expected visible binder, encountered invisible binder: "
              String -> String -> String
forall a. [a] -> [a] -> [a]
++ TyVarBndrUnit -> String
forall a. Show a => a -> String
show TyVarBndrUnit
decl_bndr
    -- This should not happen, per precondition (1).
    go_fun_args Map Name Kind
_ FunArgs
_ [] =
      String -> q [TyVarBndr_ ForAllTyFlag]
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"matchUpSigWithDecl.go_fun_args: Too few binders"

    go_invis_tvbs ::
         Map Name Type
      -> [TyVarBndrSpec]
      -> FunArgs
      -> [TyVarBndrVis]
      -> q [TyVarBndr_ ForAllTyFlag]
    go_invis_tvbs :: Map Name Kind
-> [TyVarBndrSpec]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_invis_tvbs Map Name Kind
subst [] FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs =
      Map Name Kind
-> FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
go_fun_args Map Name Kind
subst FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
    go_invis_tvbs Map Name Kind
subst (TyVarBndrSpec
invis_tvb:[TyVarBndrSpec]
invis_tvbs) FunArgs
sig_args [TyVarBndrUnit]
decl_bndrss =
      case [TyVarBndrUnit]
decl_bndrss of
        [] -> q [TyVarBndr_ ForAllTyFlag]
skip_invis_bndr
        TyVarBndrUnit
decl_bndr:[TyVarBndrUnit]
decl_bndrs ->
          case TyVarBndrUnit -> ()
forall flag. TyVarBndr_ flag -> flag
tvFlag TyVarBndrUnit
decl_bndr of
            ()
BndrReq -> q [TyVarBndr_ ForAllTyFlag]
skip_invis_bndr
            -- If the next decl_bndr is an invisible @-binder, then we must match it
            -- against the invisible forall–bound variable in the kind.
            ()
BndrInvis -> do
              let (Map Name Kind
subst', TyVarBndrSpec
sig_tvb) = Map Name Kind
-> TyVarBndrSpec -> TyVarBndrUnit -> (Map Name Kind, TyVarBndrSpec)
forall flag.
Map Name Kind
-> TyVarBndr_ flag
-> TyVarBndrUnit
-> (Map Name Kind, TyVarBndr_ flag)
match_tvbs Map Name Kind
subst TyVarBndrSpec
invis_tvb TyVarBndrUnit
decl_bndr
              [TyVarBndr_ ForAllTyFlag]
sig_args' <- Map Name Kind
-> [TyVarBndrSpec]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_invis_tvbs Map Name Kind
subst' [TyVarBndrSpec]
invis_tvbs FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
              [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a. a -> q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Specificity -> ForAllTyFlag)
-> TyVarBndrSpec -> TyVarBndr_ ForAllTyFlag
forall flag flag'.
(flag -> flag') -> TyVarBndr_ flag -> TyVarBndr_ flag'
mapTVFlag Specificity -> ForAllTyFlag
Invisible TyVarBndrSpec
sig_tvb TyVarBndr_ ForAllTyFlag
-> [TyVarBndr_ ForAllTyFlag] -> [TyVarBndr_ ForAllTyFlag]
forall a. a -> [a] -> [a]
: [TyVarBndr_ ForAllTyFlag]
sig_args')
      where
        -- There is an invisible forall in the kind without a corresponding
        -- invisible @-binder, which is allowed. In this case, we simply apply
        -- the substitution and recurse.
        skip_invis_bndr :: q [TyVarBndr_ ForAllTyFlag]
        skip_invis_bndr :: q [TyVarBndr_ ForAllTyFlag]
skip_invis_bndr = do
          let (Map Name Kind
subst', TyVarBndrSpec
invis_tvb') = Map Name Kind -> TyVarBndrSpec -> (Map Name Kind, TyVarBndrSpec)
forall flag.
Map Name Kind
-> TyVarBndr_ flag -> (Map Name Kind, TyVarBndr_ flag)
substTvb Map Name Kind
subst TyVarBndrSpec
invis_tvb
          [TyVarBndr_ ForAllTyFlag]
sig_args' <- Map Name Kind
-> [TyVarBndrSpec]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_invis_tvbs Map Name Kind
subst' [TyVarBndrSpec]
invis_tvbs FunArgs
sig_args [TyVarBndrUnit]
decl_bndrss
          [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a. a -> q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag])
-> [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a b. (a -> b) -> a -> b
$ (Specificity -> ForAllTyFlag)
-> TyVarBndrSpec -> TyVarBndr_ ForAllTyFlag
forall flag flag'.
(flag -> flag') -> TyVarBndr_ flag -> TyVarBndr_ flag'
mapTVFlag Specificity -> ForAllTyFlag
Invisible TyVarBndrSpec
invis_tvb' TyVarBndr_ ForAllTyFlag
-> [TyVarBndr_ ForAllTyFlag] -> [TyVarBndr_ ForAllTyFlag]
forall a. a -> [a] -> [a]
: [TyVarBndr_ ForAllTyFlag]
sig_args'

    go_vis_tvbs ::
         Map Name Type
      -> [TyVarBndrUnit]
      -> FunArgs
      -> [TyVarBndrVis]
      -> q [TyVarBndr_ ForAllTyFlag]
    go_vis_tvbs :: Map Name Kind
-> [TyVarBndrUnit]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_vis_tvbs Map Name Kind
subst [] FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs =
      Map Name Kind
-> FunArgs -> [TyVarBndrUnit] -> q [TyVarBndr_ ForAllTyFlag]
go_fun_args Map Name Kind
subst FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
    -- This should not happen, per precondition (1).
    go_vis_tvbs Map Name Kind
_ (TyVarBndrUnit
_:[TyVarBndrUnit]
_) FunArgs
_ [] =
      String -> q [TyVarBndr_ ForAllTyFlag]
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"matchUpSigWithDecl.go_vis_tvbs: Too few binders"
    go_vis_tvbs Map Name Kind
subst (TyVarBndrUnit
vis_tvb:[TyVarBndrUnit]
vis_tvbs) FunArgs
sig_args (TyVarBndrUnit
decl_bndr:[TyVarBndrUnit]
decl_bndrs) = do
      case TyVarBndrUnit -> ()
forall flag. TyVarBndr_ flag -> flag
tvFlag TyVarBndrUnit
decl_bndr of
        -- If the next decl_bndr is required, then we must match it against the
        -- visible forall–bound variable in the kind.
        ()
BndrReq -> do
          let (Map Name Kind
subst', TyVarBndrUnit
sig_tvb) = Map Name Kind
-> TyVarBndrUnit -> TyVarBndrUnit -> (Map Name Kind, TyVarBndrUnit)
forall flag.
Map Name Kind
-> TyVarBndr_ flag
-> TyVarBndrUnit
-> (Map Name Kind, TyVarBndr_ flag)
match_tvbs Map Name Kind
subst TyVarBndrUnit
vis_tvb TyVarBndrUnit
decl_bndr
          [TyVarBndr_ ForAllTyFlag]
sig_args' <- Map Name Kind
-> [TyVarBndrUnit]
-> FunArgs
-> [TyVarBndrUnit]
-> q [TyVarBndr_ ForAllTyFlag]
go_vis_tvbs Map Name Kind
subst' [TyVarBndrUnit]
vis_tvbs FunArgs
sig_args [TyVarBndrUnit]
decl_bndrs
          [TyVarBndr_ ForAllTyFlag] -> q [TyVarBndr_ ForAllTyFlag]
forall a. a -> q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((() -> ForAllTyFlag) -> TyVarBndrUnit -> TyVarBndr_ ForAllTyFlag
forall flag flag'.
(flag -> flag') -> TyVarBndr_ flag -> TyVarBndr_ flag'
mapTVFlag (ForAllTyFlag -> () -> ForAllTyFlag
forall a b. a -> b -> a
const ForAllTyFlag
Required) TyVarBndrUnit
sig_tvb TyVarBndr_ ForAllTyFlag
-> [TyVarBndr_ ForAllTyFlag] -> [TyVarBndr_ ForAllTyFlag]
forall a. a -> [a] -> [a]
: [TyVarBndr_ ForAllTyFlag]
sig_args')
        -- We have a visible forall in the kind, but an invisible @-binder as
        -- the next decl_bndr. This is ill kinded, so throw an error.
        --
        -- This should not happen, per precondition (2).
        ()
BndrInvis ->
          String -> q [TyVarBndr_ ForAllTyFlag]
forall a. String -> q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> q [TyVarBndr_ ForAllTyFlag])
-> String -> q [TyVarBndr_ ForAllTyFlag]
forall a b. (a -> b) -> a -> b
$ String
"matchUpSigWithDecl.go_vis_tvbs: Expected visible binder, encountered invisible binder: "
              String -> String -> String
forall a. [a] -> [a] -> [a]
++ TyVarBndrUnit -> String
forall a. Show a => a -> String
show TyVarBndrUnit
decl_bndr

    -- @match_tvbs subst sig_tvb decl_bndr@ will match the kind of @decl_bndr@
    -- against the kind of @sig_tvb@ to produce a new kind. This function
    -- produces two values as output:
    --
    -- 1. A new @subst@ that has been extended such that the name of @sig_tvb@
    --    maps to the name of @decl_bndr@. (See the Haddocks for the @Map Name
    --    Type@ argument to @go_fun_args@ for an explanation of why we do this.)
    --
    -- 2. A 'TyVarBndrSpec' that has the name of @decl_bndr@, but with the new
    --    kind resulting from matching.
    match_tvbs ::
         Map Name Type
      -> TyVarBndr_ flag
      -> TyVarBndrVis
      -> (Map Name Type, TyVarBndr_ flag)
    match_tvbs :: forall flag.
Map Name Kind
-> TyVarBndr_ flag
-> TyVarBndrUnit
-> (Map Name Kind, TyVarBndr_ flag)
match_tvbs Map Name Kind
subst TyVarBndr_ flag
sig_tvb TyVarBndrUnit
decl_bndr =
      let decl_bndr_name :: Name
decl_bndr_name = TyVarBndrUnit -> Name
forall flag. TyVarBndr_ flag -> Name
tvName TyVarBndrUnit
decl_bndr
          mb_decl_bndr_kind :: Maybe Kind
mb_decl_bndr_kind = TyVarBndrUnit -> Maybe Kind
forall flag. TyVarBndr_ flag -> Maybe Kind
extractTvbKind_maybe TyVarBndrUnit
decl_bndr

          sig_tvb_name :: Name
sig_tvb_name = TyVarBndr_ flag -> Name
forall flag. TyVarBndr_ flag -> Name
tvName TyVarBndr_ flag
sig_tvb
          sig_tvb_flag :: flag
sig_tvb_flag = TyVarBndr_ flag -> flag
forall flag. TyVarBndr_ flag -> flag
tvFlag TyVarBndr_ flag
sig_tvb
          mb_sig_tvb_kind :: Maybe Kind
mb_sig_tvb_kind = Map Name Kind -> Kind -> Kind
forall a. TypeSubstitution a => Map Name Kind -> a -> a
applySubstitution Map Name Kind
subst (Kind -> Kind) -> Maybe Kind -> Maybe Kind
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TyVarBndr_ flag -> Maybe Kind
forall flag. TyVarBndr_ flag -> Maybe Kind
extractTvbKind_maybe TyVarBndr_ flag
sig_tvb

          mb_kind :: Maybe Kind
          mb_kind :: Maybe Kind
mb_kind =
            case (Maybe Kind
mb_decl_bndr_kind, Maybe Kind
mb_sig_tvb_kind) of
              (Maybe Kind
Nothing,             Maybe Kind
Nothing)           -> Maybe Kind
forall a. Maybe a
Nothing
              (Just Kind
decl_bndr_kind, Maybe Kind
Nothing)           -> Kind -> Maybe Kind
forall a. a -> Maybe a
Just Kind
decl_bndr_kind
              (Maybe Kind
Nothing,             Just Kind
sig_tvb_kind) -> Kind -> Maybe Kind
forall a. a -> Maybe a
Just Kind
sig_tvb_kind
              (Just Kind
decl_bndr_kind, Just Kind
sig_tvb_kind) -> do
                Map Name Kind
match_subst <- Kind -> Kind -> Maybe (Map Name Kind)
matchTy Kind
decl_bndr_kind Kind
sig_tvb_kind
                Kind -> Maybe Kind
forall a. a -> Maybe a
Just (Kind -> Maybe Kind) -> Kind -> Maybe Kind
forall a b. (a -> b) -> a -> b
$ Map Name Kind -> Kind -> Kind
forall a. TypeSubstitution a => Map Name Kind -> a -> a
applySubstitution Map Name Kind
match_subst Kind
decl_bndr_kind

          subst' :: Map Name Kind
subst' = Name -> Kind -> Map Name Kind -> Map Name Kind
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Name
sig_tvb_name (Name -> Kind
VarT Name
decl_bndr_name) Map Name Kind
subst
          sig_tvb' :: TyVarBndr_ flag
sig_tvb' = case Maybe Kind
mb_kind of
            Maybe Kind
Nothing   -> Name -> flag -> TyVarBndr_ flag
forall flag. Name -> flag -> TyVarBndr_ flag
plainTVFlag Name
decl_bndr_name flag
sig_tvb_flag
            Just Kind
kind -> Name -> flag -> Kind -> TyVarBndr_ flag
forall flag. Name -> flag -> Kind -> TyVarBndr_ flag
kindedTVFlag Name
decl_bndr_name flag
sig_tvb_flag Kind
kind in

      (Map Name Kind
subst', TyVarBndr_ flag
sig_tvb')

-- Collect the invisible type variable binders from a sequence of FunArgs.
filterInvisTvbArgs :: FunArgs -> [TyVarBndrSpec]
filterInvisTvbArgs :: FunArgs -> [TyVarBndrSpec]
filterInvisTvbArgs FunArgs
FANil           = []
filterInvisTvbArgs (FACxt  [Kind]
_ FunArgs
args) = FunArgs -> [TyVarBndrSpec]
filterInvisTvbArgs FunArgs
args
filterInvisTvbArgs (FAAnon Kind
_ FunArgs
args) = FunArgs -> [TyVarBndrSpec]
filterInvisTvbArgs FunArgs
args
filterInvisTvbArgs (FAForalls ForallTelescope
tele FunArgs
args) =
  let res :: [TyVarBndrSpec]
res = FunArgs -> [TyVarBndrSpec]
filterInvisTvbArgs FunArgs
args in
  case ForallTelescope
tele of
    ForallVis   [TyVarBndrUnit]
_     -> [TyVarBndrSpec]
res
    ForallInvis [TyVarBndrSpec]
tvbs' -> [TyVarBndrSpec]
tvbs' [TyVarBndrSpec] -> [TyVarBndrSpec] -> [TyVarBndrSpec]
forall a. [a] -> [a] -> [a]
++ [TyVarBndrSpec]
res

-- | Take a telescope of 'TyVarBndr's, find the free variables in their kinds,
-- and sort them in reverse topological order to ensure that they are well
-- scoped. Because the argument list is assumed to be telescoping, kind
-- variables that are bound earlier in the list are not returned. For example,
-- this:
--
-- @
-- 'freeKindVariablesWellScoped' [a :: k, b :: Proxy a]
-- @
--
-- Will return @[k]@, not @[k, a]@, since @a@ is bound earlier by @a :: k@.
freeKindVariablesWellScoped :: [TyVarBndr_ flag] -> [TyVarBndrUnit]
freeKindVariablesWellScoped :: forall flag. [TyVarBndr_ flag] -> [TyVarBndrUnit]
freeKindVariablesWellScoped [TyVarBndr_ flag]
tvbs =
  (TyVarBndrUnit -> [TyVarBndrUnit] -> [TyVarBndrUnit])
-> [TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\TyVarBndrUnit
tvb [TyVarBndrUnit]
kvs ->
          (Kind -> [TyVarBndrUnit]) -> Maybe Kind -> [TyVarBndrUnit]
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Kind
t -> [Kind] -> [TyVarBndrUnit]
freeVariablesWellScoped [Kind
t]) (TyVarBndrUnit -> Maybe Kind
forall flag. TyVarBndr_ flag -> Maybe Kind
extractTvbKind_maybe TyVarBndrUnit
tvb) [TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
forall a. Eq a => [a] -> [a] -> [a]
`List.union`
          (TyVarBndrUnit -> TyVarBndrUnit -> Bool)
-> TyVarBndrUnit -> [TyVarBndrUnit] -> [TyVarBndrUnit]
forall a. (a -> a -> Bool) -> a -> [a] -> [a]
List.deleteBy (Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Name -> Name -> Bool)
-> (TyVarBndrUnit -> Name)
-> TyVarBndrUnit
-> TyVarBndrUnit
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` TyVarBndrUnit -> Name
forall flag. TyVarBndr_ flag -> Name
tvName) TyVarBndrUnit
tvb [TyVarBndrUnit]
kvs)
        []
        (() -> [TyVarBndr_ flag] -> [TyVarBndrUnit]
forall newFlag oldFlag.
newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
changeTVFlags () [TyVarBndr_ flag]
tvbs)

-- | @'matchTy' tmpl targ@ matches a type template @tmpl@ against a type target
-- @targ@. This returns a Map from names of type variables in the type template
-- to types if the types indeed match up, or @Nothing@ otherwise. In the @Just@
-- case, it is guaranteed that every type variable mentioned in the template is
-- mapped by the returned substitution.
--
-- Note that this function will always return @Nothing@ if the template contains
-- an explicit kind signature or visible kind application.
--
-- This is heavily inspired by the function of the same name in
-- "Language.Haskell.TH.Desugar.Subst", which works over 'DType's instead of
-- 'Type's.
matchTy :: Type -> Type -> Maybe (Map Name Type)
matchTy :: Kind -> Kind -> Maybe (Map Name Kind)
matchTy (VarT Name
var_name) Kind
arg = Map Name Kind -> Maybe (Map Name Kind)
forall a. a -> Maybe a
Just (Map Name Kind -> Maybe (Map Name Kind))
-> Map Name Kind -> Maybe (Map Name Kind)
forall a b. (a -> b) -> a -> b
$ Name -> Kind -> Map Name Kind
forall k a. k -> a -> Map k a
Map.singleton Name
var_name Kind
arg
matchTy (SigT {})     Kind
_ = Maybe (Map Name Kind)
forall a. Maybe a
Nothing
matchTy Kind
pat (SigT     Kind
ty Kind
_ki) = Kind -> Kind -> Maybe (Map Name Kind)
matchTy Kind
pat Kind
ty
#if __GLASGOW_HASKELL__ >= 807
matchTy (AppKindT {}) Kind
_ = Maybe (Map Name Kind)
forall a. Maybe a
Nothing
matchTy Kind
pat (AppKindT Kind
ty Kind
_ki) = Kind -> Kind -> Maybe (Map Name Kind)
matchTy Kind
pat Kind
ty
#endif
matchTy (ForallT {}) Kind
_ =
  String -> Maybe (Map Name Kind)
forall a. HasCallStack => String -> a
error String
"Cannot match a forall in a pattern"
matchTy Kind
_ (ForallT {}) =
  String -> Maybe (Map Name Kind)
forall a. HasCallStack => String -> a
error String
"Cannot match a forall in a target"
matchTy (AppT Kind
pat1 Kind
pat2) (AppT Kind
arg1 Kind
arg2) =
  [Maybe (Map Name Kind)] -> Maybe (Map Name Kind)
unionMaybeSubsts [Kind -> Kind -> Maybe (Map Name Kind)
matchTy Kind
pat1 Kind
arg1, Kind -> Kind -> Maybe (Map Name Kind)
matchTy Kind
pat2 Kind
arg2]
matchTy (ConT Name
pat_con) (ConT Name
arg_con)
  | Name
pat_con Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
arg_con
  = Map Name Kind -> Maybe (Map Name Kind)
forall a. a -> Maybe a
Just Map Name Kind
forall k a. Map k a
Map.empty
  | Bool
otherwise
  = Maybe (Map Name Kind)
forall a. Maybe a
Nothing
matchTy Kind
ArrowT Kind
ArrowT = Map Name Kind -> Maybe (Map Name Kind)
forall a. a -> Maybe a
Just Map Name Kind
forall k a. Map k a
Map.empty
matchTy (LitT TyLit
pat_lit) (LitT TyLit
arg_lit)
  | TyLit
pat_lit TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
arg_lit
  = Map Name Kind -> Maybe (Map Name Kind)
forall a. a -> Maybe a
Just Map Name Kind
forall k a. Map k a
Map.empty
  | Bool
otherwise
  = Maybe (Map Name Kind)
forall a. Maybe a
Nothing
matchTy Kind
_ Kind
_ = Maybe (Map Name Kind)
forall a. Maybe a
Nothing

-- | This is inspired by the function of the same name in
-- "Language.Haskell.TH.Desugar.Subst".
unionMaybeSubsts :: [Maybe (Map Name Type)] -> Maybe (Map Name Type)
unionMaybeSubsts :: [Maybe (Map Name Kind)] -> Maybe (Map Name Kind)
unionMaybeSubsts = (Maybe (Map Name Kind)
 -> Maybe (Map Name Kind) -> Maybe (Map Name Kind))
-> Maybe (Map Name Kind)
-> [Maybe (Map Name Kind)]
-> Maybe (Map Name Kind)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' Maybe (Map Name Kind)
-> Maybe (Map Name Kind) -> Maybe (Map Name Kind)
union_subst1 (Map Name Kind -> Maybe (Map Name Kind)
forall a. a -> Maybe a
Just Map Name Kind
forall k a. Map k a
Map.empty)
  where
    union_subst1 ::
      Maybe (Map Name Type) -> Maybe (Map Name Type) -> Maybe (Map Name Type)
    union_subst1 :: Maybe (Map Name Kind)
-> Maybe (Map Name Kind) -> Maybe (Map Name Kind)
union_subst1 Maybe (Map Name Kind)
ma Maybe (Map Name Kind)
mb = do
      Map Name Kind
a <- Maybe (Map Name Kind)
ma
      Map Name Kind
b <- Maybe (Map Name Kind)
mb
      Map Name Kind -> Map Name Kind -> Maybe (Map Name Kind)
unionSubsts Map Name Kind
a Map Name Kind
b

-- | Computes the union of two substitutions. Fails if both subsitutions map
-- the same variable to different types.
--
-- This is inspired by the function of the same name in
-- "Language.Haskell.TH.Desugar.Subst".
unionSubsts :: Map Name Type -> Map Name Type -> Maybe (Map Name Type)
unionSubsts :: Map Name Kind -> Map Name Kind -> Maybe (Map Name Kind)
unionSubsts Map Name Kind
a Map Name Kind
b =
  let shared_key_set :: Set Name
shared_key_set = Map Name Kind -> Set Name
forall k a. Map k a -> Set k
Map.keysSet Map Name Kind
a Set Name -> Set Name -> Set Name
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` Map Name Kind -> Set Name
forall k a. Map k a -> Set k
Map.keysSet Map Name Kind
b
      matches_up :: Bool
matches_up     = (Name -> Bool -> Bool) -> Bool -> Set Name -> Bool
forall a b. (a -> b -> b) -> b -> Set a -> b
Set.foldr (\Name
name -> ((Map Name Kind
a Map Name Kind -> Name -> Kind
forall k a. Ord k => Map k a -> k -> a
Map.! Name
name) Kind -> Kind -> Bool
forall a. Eq a => a -> a -> Bool
== (Map Name Kind
b Map Name Kind -> Name -> Kind
forall k a. Ord k => Map k a -> k -> a
Map.! Name
name) Bool -> Bool -> Bool
&&))
                                 Bool
True Set Name
shared_key_set
  in
  if Bool
matches_up then Map Name Kind -> Maybe (Map Name Kind)
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Name Kind
a Map Name Kind -> Map Name Kind -> Map Name Kind
forall k a. Ord k => Map k a -> Map k a -> Map k a
`Map.union` Map Name Kind
b) else Maybe (Map Name Kind)
forall a. Maybe a
Nothing

-- | This is inspired by the function of the same name in
-- "Language.Haskell.TH.Desugar.Subst.Capturing".
substTvb :: Map Name Kind -> TyVarBndr_ flag -> (Map Name Kind, TyVarBndr_ flag)
substTvb :: forall flag.
Map Name Kind
-> TyVarBndr_ flag -> (Map Name Kind, TyVarBndr_ flag)
substTvb Map Name Kind
s TyVarBndr_ flag
tvb = (Name -> Map Name Kind -> Map Name Kind
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete (TyVarBndr_ flag -> Name
forall flag. TyVarBndr_ flag -> Name
tvName TyVarBndr_ flag
tvb) Map Name Kind
s, (Kind -> Kind) -> TyVarBndr_ flag -> TyVarBndr_ flag
forall flag. (Kind -> Kind) -> TyVarBndr_ flag -> TyVarBndr_ flag
mapTVKind (Map Name Kind -> Kind -> Kind
forall a. TypeSubstitution a => Map Name Kind -> a -> a
applySubstitution Map Name Kind
s) TyVarBndr_ flag
tvb)

-- This is heavily inspired by the `swizzleTcb` function in GHC:
-- https://gitlab.haskell.org/ghc/ghc/-/blob/cec903899234bf9e25ea404477ba846ac1e963bb/compiler/GHC/Tc/Gen/HsType.hs#L2741-2755
swizzleTvb ::
     Map Name Name
     -- ^ A \"swizzle environment\" (i.e., a map from binder names in a
     -- standalone kind signature to binder names in the corresponding
     -- type-level declaration).
  -> Map Name Type
     -- ^ Like the swizzle environment, but as a full-blown substitution.
  -> TyVarBndr_ flag
  -> (Map Name Type, TyVarBndr_ flag)
swizzleTvb :: forall flag.
Map Name Name
-> Map Name Kind
-> TyVarBndr_ flag
-> (Map Name Kind, TyVarBndr_ flag)
swizzleTvb Map Name Name
swizzle_env Map Name Kind
subst TyVarBndr_ flag
tvb =
  (Map Name Kind
subst', TyVarBndr_ flag
tvb2)
  where
    subst' :: Map Name Kind
subst' = Name -> Kind -> Map Name Kind -> Map Name Kind
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Name
tvb_name (Name -> Kind
VarT (TyVarBndr_ flag -> Name
forall flag. TyVarBndr_ flag -> Name
tvName TyVarBndr_ flag
tvb2)) Map Name Kind
subst
    tvb_name :: Name
tvb_name = TyVarBndr_ flag -> Name
forall flag. TyVarBndr_ flag -> Name
tvName TyVarBndr_ flag
tvb
    tvb1 :: TyVarBndr_ flag
tvb1 = (Kind -> Kind) -> TyVarBndr_ flag -> TyVarBndr_ flag
forall flag. (Kind -> Kind) -> TyVarBndr_ flag -> TyVarBndr_ flag
mapTVKind (Map Name Kind -> Kind -> Kind
forall a. TypeSubstitution a => Map Name Kind -> a -> a
applySubstitution Map Name Kind
subst) TyVarBndr_ flag
tvb
    tvb2 :: TyVarBndr_ flag
tvb2 =
      case Name -> Map Name Name -> Maybe Name
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
tvb_name Map Name Name
swizzle_env of
        Just Name
user_name -> (Name -> Name) -> TyVarBndr_ flag -> TyVarBndr_ flag
forall flag. (Name -> Name) -> TyVarBndr_ flag -> TyVarBndr_ flag
mapTVName (Name -> Name -> Name
forall a b. a -> b -> a
const Name
user_name) TyVarBndr_ flag
tvb1
        Maybe Name
Nothing        -> TyVarBndr_ flag
tvb1

-- The visibility of a binder in a type-level declaration. This generalizes
-- 'Specificity' (which lacks an equivalent to 'Required') and 'BndrVis' (which
-- lacks an equivalent to @'Invisible' 'Inferred'@).
--
-- This is heavily inspired by a data type of the same name in GHC:
-- https://gitlab.haskell.org/ghc/ghc/-/blob/98597ad5fca81544d74f721fb508295fd2650232/compiler/GHC/Types/Var.hs#L458-465
data ForAllTyFlag
  = Invisible !Specificity
    -- ^ If the 'Specificity' value is 'SpecifiedSpec', then the binder is
    -- permitted by request (e.g., @\@a@). If the 'Specificity' value is
    -- 'InferredSpec', then the binder is prohibited from appearing in source
    -- Haskell (e.g., @\@{a}@).
  | Required
    -- ^ The binder is required to appear in source Haskell (e.g., @a@).
  deriving (Int -> ForAllTyFlag -> String -> String
[ForAllTyFlag] -> String -> String
ForAllTyFlag -> String
(Int -> ForAllTyFlag -> String -> String)
-> (ForAllTyFlag -> String)
-> ([ForAllTyFlag] -> String -> String)
-> Show ForAllTyFlag
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ForAllTyFlag -> String -> String
showsPrec :: Int -> ForAllTyFlag -> String -> String
$cshow :: ForAllTyFlag -> String
show :: ForAllTyFlag -> String
$cshowList :: [ForAllTyFlag] -> String -> String
showList :: [ForAllTyFlag] -> String -> String
Show, ForAllTyFlag -> ForAllTyFlag -> Bool
(ForAllTyFlag -> ForAllTyFlag -> Bool)
-> (ForAllTyFlag -> ForAllTyFlag -> Bool) -> Eq ForAllTyFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ForAllTyFlag -> ForAllTyFlag -> Bool
== :: ForAllTyFlag -> ForAllTyFlag -> Bool
$c/= :: ForAllTyFlag -> ForAllTyFlag -> Bool
/= :: ForAllTyFlag -> ForAllTyFlag -> Bool
Eq, Eq ForAllTyFlag
Eq ForAllTyFlag =>
(ForAllTyFlag -> ForAllTyFlag -> Ordering)
-> (ForAllTyFlag -> ForAllTyFlag -> Bool)
-> (ForAllTyFlag -> ForAllTyFlag -> Bool)
-> (ForAllTyFlag -> ForAllTyFlag -> Bool)
-> (ForAllTyFlag -> ForAllTyFlag -> Bool)
-> (ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag)
-> (ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag)
-> Ord ForAllTyFlag
ForAllTyFlag -> ForAllTyFlag -> Bool
ForAllTyFlag -> ForAllTyFlag -> Ordering
ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ForAllTyFlag -> ForAllTyFlag -> Ordering
compare :: ForAllTyFlag -> ForAllTyFlag -> Ordering
$c< :: ForAllTyFlag -> ForAllTyFlag -> Bool
< :: ForAllTyFlag -> ForAllTyFlag -> Bool
$c<= :: ForAllTyFlag -> ForAllTyFlag -> Bool
<= :: ForAllTyFlag -> ForAllTyFlag -> Bool
$c> :: ForAllTyFlag -> ForAllTyFlag -> Bool
> :: ForAllTyFlag -> ForAllTyFlag -> Bool
$c>= :: ForAllTyFlag -> ForAllTyFlag -> Bool
>= :: ForAllTyFlag -> ForAllTyFlag -> Bool
$cmax :: ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag
max :: ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag
$cmin :: ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag
min :: ForAllTyFlag -> ForAllTyFlag -> ForAllTyFlag
Ord, Typeable ForAllTyFlag
Typeable ForAllTyFlag =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ForAllTyFlag -> c ForAllTyFlag)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ForAllTyFlag)
-> (ForAllTyFlag -> Constr)
-> (ForAllTyFlag -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ForAllTyFlag))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ForAllTyFlag))
-> ((forall b. Data b => b -> b) -> ForAllTyFlag -> ForAllTyFlag)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r)
-> (forall u. (forall d. Data d => d -> u) -> ForAllTyFlag -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ForAllTyFlag -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag)
-> Data ForAllTyFlag
ForAllTyFlag -> Constr
ForAllTyFlag -> DataType
(forall b. Data b => b -> b) -> ForAllTyFlag -> ForAllTyFlag
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ForAllTyFlag -> u
forall u. (forall d. Data d => d -> u) -> ForAllTyFlag -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ForAllTyFlag
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ForAllTyFlag -> c ForAllTyFlag
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ForAllTyFlag)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ForAllTyFlag)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ForAllTyFlag -> c ForAllTyFlag
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ForAllTyFlag -> c ForAllTyFlag
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ForAllTyFlag
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ForAllTyFlag
$ctoConstr :: ForAllTyFlag -> Constr
toConstr :: ForAllTyFlag -> Constr
$cdataTypeOf :: ForAllTyFlag -> DataType
dataTypeOf :: ForAllTyFlag -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ForAllTyFlag)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ForAllTyFlag)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ForAllTyFlag)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ForAllTyFlag)
$cgmapT :: (forall b. Data b => b -> b) -> ForAllTyFlag -> ForAllTyFlag
gmapT :: (forall b. Data b => b -> b) -> ForAllTyFlag -> ForAllTyFlag
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ForAllTyFlag -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ForAllTyFlag -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ForAllTyFlag -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ForAllTyFlag -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ForAllTyFlag -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ForAllTyFlag -> m ForAllTyFlag
Data, (forall x. ForAllTyFlag -> Rep ForAllTyFlag x)
-> (forall x. Rep ForAllTyFlag x -> ForAllTyFlag)
-> Generic ForAllTyFlag
forall x. Rep ForAllTyFlag x -> ForAllTyFlag
forall x. ForAllTyFlag -> Rep ForAllTyFlag x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ForAllTyFlag -> Rep ForAllTyFlag x
from :: forall x. ForAllTyFlag -> Rep ForAllTyFlag x
$cto :: forall x. Rep ForAllTyFlag x -> ForAllTyFlag
to :: forall x. Rep ForAllTyFlag x -> ForAllTyFlag
Generic, (forall (m :: * -> *). Quote m => ForAllTyFlag -> m Exp)
-> (forall (m :: * -> *).
    Quote m =>
    ForAllTyFlag -> Code m ForAllTyFlag)
-> Lift ForAllTyFlag
forall t.
(forall (m :: * -> *). Quote m => t -> m Exp)
-> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
forall (m :: * -> *). Quote m => ForAllTyFlag -> m Exp
forall (m :: * -> *).
Quote m =>
ForAllTyFlag -> Code m ForAllTyFlag
$clift :: forall (m :: * -> *). Quote m => ForAllTyFlag -> m Exp
lift :: forall (m :: * -> *). Quote m => ForAllTyFlag -> m Exp
$cliftTyped :: forall (m :: * -> *).
Quote m =>
ForAllTyFlag -> Code m ForAllTyFlag
liftTyped :: forall (m :: * -> *).
Quote m =>
ForAllTyFlag -> Code m ForAllTyFlag
Lift)

instance DefaultBndrFlag ForAllTyFlag where
  defaultBndrFlag :: ForAllTyFlag
defaultBndrFlag = ForAllTyFlag
Required

#if __GLASGOW_HASKELL__ >= 900
instance PprFlag ForAllTyFlag where
  pprTyVarBndr :: TyVarBndr_ ForAllTyFlag -> Doc
pprTyVarBndr (PlainTV Name
nm ForAllTyFlag
vis) =
    ForAllTyFlag -> Doc -> Doc
pprForAllTyFlag ForAllTyFlag
vis (Name -> Doc
forall a. Ppr a => a -> Doc
ppr Name
nm)
  pprTyVarBndr (KindedTV Name
nm ForAllTyFlag
vis Kind
k) =
    ForAllTyFlag -> Doc -> Doc
pprForAllTyFlag ForAllTyFlag
vis (Doc -> Doc
Ppr.parens (Name -> Doc
forall a. Ppr a => a -> Doc
ppr Name
nm Doc -> Doc -> Doc
Ppr.<+> Doc
Ppr.dcolon Doc -> Doc -> Doc
Ppr.<+> Kind -> Doc
forall a. Ppr a => a -> Doc
ppr Kind
k))

pprForAllTyFlag :: ForAllTyFlag -> Ppr.Doc -> Ppr.Doc
pprForAllTyFlag :: ForAllTyFlag -> Doc -> Doc
pprForAllTyFlag (Invisible Specificity
SpecifiedSpec) Doc
d = Char -> Doc
Ppr.char Char
'@' Doc -> Doc -> Doc
Ppr.<> Doc
d
pprForAllTyFlag (Invisible Specificity
InferredSpec)  Doc
d = Doc -> Doc
Ppr.braces Doc
d
pprForAllTyFlag ForAllTyFlag
Required                  Doc
d = Doc
d
#endif

-- | Convert a list of @'TyVarBndr' 'ForAllTyFlag'@s to a list of
-- 'TyVarBndrSpec's, which is suitable for use in an invisible @forall@.
-- Specifically:
--
-- * Variable binders that use @'Invisible' spec@ are converted to @spec@.
--
-- * Variable binders that are 'Required' are converted to 'SpecifiedSpec',
--   as all of the 'TyVarBndrSpec's are invisible. As an example of how this
--   is used, consider what would happen when singling this data type:
--
--   @
--   type T :: forall k -> k -> Type
--   data T k (a :: k) where ...
--   @
--
--   Here, the @k@ binder is 'Required'. When we produce the standalone kind
--   signature for the singled data type, we use 'tvbForAllTyFlagsToSpecs' to
--   produce the type variable binders in the outermost @forall@:
--
--   @
--   type ST :: forall k (a :: k). T k a -> Type
--   data ST z where ...
--   @
--
--   Note that the @k@ is bound visibily (i.e., using 'SpecifiedSpec') in the
--   outermost, invisible @forall@.
tvbForAllTyFlagsToSpecs :: [TyVarBndr_ ForAllTyFlag] -> [TyVarBndrSpec]
tvbForAllTyFlagsToSpecs :: [TyVarBndr_ ForAllTyFlag] -> [TyVarBndrSpec]
tvbForAllTyFlagsToSpecs = (TyVarBndr_ ForAllTyFlag -> TyVarBndrSpec)
-> [TyVarBndr_ ForAllTyFlag] -> [TyVarBndrSpec]
forall a b. (a -> b) -> [a] -> [b]
map ((ForAllTyFlag -> Specificity)
-> TyVarBndr_ ForAllTyFlag -> TyVarBndrSpec
forall flag flag'.
(flag -> flag') -> TyVarBndr_ flag -> TyVarBndr_ flag'
mapTVFlag ForAllTyFlag -> Specificity
to_spec)
  where
   to_spec :: ForAllTyFlag -> Specificity
   to_spec :: ForAllTyFlag -> Specificity
to_spec (Invisible Specificity
spec) = Specificity
spec
   to_spec ForAllTyFlag
Required         = Specificity
SpecifiedSpec

-- | Convert a list of @'TyVarBndr' 'ForAllTyFlag'@s to a list of
-- 'TyVarBndrVis'es, which is suitable for use in a type-level declaration
-- (e.g., the @var_1 ... var_n@ in @class C var_1 ... var_n@). Specifically:
--
-- * Variable binders that use @'Invisible' 'InferredSpec'@ are dropped
--   entirely. Such binders cannot be represented in source Haskell.
--
-- * Variable binders that use @'Invisible' 'SpecifiedSpec'@ are converted to
--   'BndrInvis'.
--
-- * Variable binders that are 'Required' are converted to 'BndrReq'.
tvbForAllTyFlagsToBndrVis :: [TyVarBndr_ ForAllTyFlag] -> [TyVarBndrVis]
tvbForAllTyFlagsToBndrVis :: [TyVarBndr_ ForAllTyFlag] -> [TyVarBndrUnit]
tvbForAllTyFlagsToBndrVis = [Maybe TyVarBndrUnit] -> [TyVarBndrUnit]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe TyVarBndrUnit] -> [TyVarBndrUnit])
-> ([TyVarBndr_ ForAllTyFlag] -> [Maybe TyVarBndrUnit])
-> [TyVarBndr_ ForAllTyFlag]
-> [TyVarBndrUnit]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TyVarBndr_ ForAllTyFlag -> Maybe TyVarBndrUnit)
-> [TyVarBndr_ ForAllTyFlag] -> [Maybe TyVarBndrUnit]
forall a b. (a -> b) -> [a] -> [b]
map ((ForAllTyFlag -> Maybe ())
-> TyVarBndr_ ForAllTyFlag -> Maybe TyVarBndrUnit
forall (f :: * -> *) flag flag'.
Applicative f =>
(flag -> f flag') -> TyVarBndr_ flag -> f (TyVarBndr_ flag')
traverseTVFlag ForAllTyFlag -> Maybe ()
to_spec_maybe)
  where
    to_spec_maybe :: ForAllTyFlag -> Maybe BndrVis
    to_spec_maybe :: ForAllTyFlag -> Maybe ()
to_spec_maybe (Invisible Specificity
InferredSpec) = Maybe ()
forall a. Maybe a
Nothing
    to_spec_maybe (Invisible Specificity
SpecifiedSpec) = () -> Maybe ()
forall a. a -> Maybe a
Just ()
bndrInvis
    to_spec_maybe ForAllTyFlag
Required = () -> Maybe ()
forall a. a -> Maybe a
Just ()
BndrReq

----------------------------------------
-- Free names, etc.
----------------------------------------

-- | Check if a name occurs anywhere within a TH tree.
nameOccursIn :: Data a => Name -> a -> Bool
nameOccursIn :: forall a. Data a => Name -> a -> Bool
nameOccursIn Name
n = (Bool -> Bool -> Bool)
-> (forall {a}. Data a => a -> Bool)
-> forall {a}. Data a => a -> Bool
forall r. (r -> r -> r) -> GenericQ r -> GenericQ r
everything Bool -> Bool -> Bool
(||) ((forall {a}. Data a => a -> Bool)
 -> forall {a}. Data a => a -> Bool)
-> (forall {a}. Data a => a -> Bool)
-> forall {a}. Data a => a -> Bool
forall a b. (a -> b) -> a -> b
$ Bool -> (Name -> Bool) -> a -> Bool
forall a b r. (Typeable a, Typeable b) => r -> (b -> r) -> a -> r
mkQ Bool
False (Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
n)

-- | Extract all Names mentioned in a TH tree.
allNamesIn :: Data a => a -> [Name]
allNamesIn :: forall a. Data a => a -> [Name]
allNamesIn = ([Name] -> [Name] -> [Name])
-> (forall a. Data a => a -> [Name])
-> forall a. Data a => a -> [Name]
forall r. (r -> r -> r) -> GenericQ r -> GenericQ r
everything [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
(++) ((forall a. Data a => a -> [Name])
 -> forall a. Data a => a -> [Name])
-> (forall a. Data a => a -> [Name])
-> forall a. Data a => a -> [Name]
forall a b. (a -> b) -> a -> b
$ [Name] -> (Name -> [Name]) -> a -> [Name]
forall a b r. (Typeable a, Typeable b) => r -> (b -> r) -> a -> r
mkQ [] (Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
:[])

-- | Extract the names bound in a @Stmt@.
--
-- This does /not/ extract any type variables bound by pattern signatures,
-- constructor patterns, or type patterns.
extractBoundNamesStmt :: Stmt -> OSet Name
extractBoundNamesStmt :: Stmt -> OSet Name
extractBoundNamesStmt (BindS Pat
pat Exp
_) = Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesStmt (LetS [Dec]
decs)   = (Dec -> OSet Name) -> [Dec] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Dec -> OSet Name
extractBoundNamesDec [Dec]
decs
extractBoundNamesStmt (NoBindS Exp
_)   = OSet Name
forall a. OSet a
OS.empty
extractBoundNamesStmt (ParS [[Stmt]]
stmtss) = ([Stmt] -> OSet Name) -> [[Stmt]] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Stmt -> OSet Name) -> [Stmt] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Stmt -> OSet Name
extractBoundNamesStmt) [[Stmt]]
stmtss
#if __GLASGOW_HASKELL__ >= 807
extractBoundNamesStmt (RecS [Stmt]
stmtss) = (Stmt -> OSet Name) -> [Stmt] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Stmt -> OSet Name
extractBoundNamesStmt [Stmt]
stmtss
#endif

-- | Extract the names bound in a @Dec@ that could appear in a @let@ expression.
--
-- This does /not/ extract any type variables bound by pattern signatures,
-- constructor patterns, or type patterns.
extractBoundNamesDec :: Dec -> OSet Name
extractBoundNamesDec :: Dec -> OSet Name
extractBoundNamesDec (FunD Name
name [Clause]
_)  = Name -> OSet Name
forall a. a -> OSet a
OS.singleton Name
name
extractBoundNamesDec (ValD Pat
pat Body
_ [Dec]
_) = Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesDec Dec
_              = OSet Name
forall a. OSet a
OS.empty

-- | Extract the names bound in a @Pat@.
--
-- This does /not/ extract any type variables bound by pattern signatures,
-- constructor patterns, or type patterns.
extractBoundNamesPat :: Pat -> OSet Name
extractBoundNamesPat :: Pat -> OSet Name
extractBoundNamesPat (LitP Lit
_)              = OSet Name
forall a. OSet a
OS.empty
extractBoundNamesPat (VarP Name
name)           = Name -> OSet Name
forall a. a -> OSet a
OS.singleton Name
name
extractBoundNamesPat (TupP [Pat]
pats)           = (Pat -> OSet Name) -> [Pat] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pat -> OSet Name
extractBoundNamesPat [Pat]
pats
extractBoundNamesPat (UnboxedTupP [Pat]
pats)    = (Pat -> OSet Name) -> [Pat] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pat -> OSet Name
extractBoundNamesPat [Pat]
pats
extractBoundNamesPat (ConP Name
_
#if __GLASGOW_HASKELL__ >= 901
                             [Kind]
_
#endif
                               [Pat]
pats)       = (Pat -> OSet Name) -> [Pat] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pat -> OSet Name
extractBoundNamesPat [Pat]
pats
extractBoundNamesPat (InfixP Pat
p1 Name
_ Pat
p2)      = Pat -> OSet Name
extractBoundNamesPat Pat
p1 OSet Name -> OSet Name -> OSet Name
forall a. Ord a => OSet a -> OSet a -> OSet a
`OS.union`
                                             Pat -> OSet Name
extractBoundNamesPat Pat
p2
extractBoundNamesPat (UInfixP Pat
p1 Name
_ Pat
p2)     = Pat -> OSet Name
extractBoundNamesPat Pat
p1 OSet Name -> OSet Name -> OSet Name
forall a. Ord a => OSet a -> OSet a -> OSet a
`OS.union`
                                             Pat -> OSet Name
extractBoundNamesPat Pat
p2
extractBoundNamesPat (ParensP Pat
pat)         = Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesPat (TildeP Pat
pat)          = Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesPat (BangP Pat
pat)           = Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesPat (AsP Name
name Pat
pat)        = Name -> OSet Name
forall a. a -> OSet a
OS.singleton Name
name OSet Name -> OSet Name -> OSet Name
forall a. Ord a => OSet a -> OSet a -> OSet a
`OS.union`
                                             Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesPat Pat
WildP                 = OSet Name
forall a. OSet a
OS.empty
extractBoundNamesPat (RecP Name
_ [FieldPat]
field_pats)   = let ([Name]
_, [Pat]
pats) = [FieldPat] -> ([Name], [Pat])
forall a b. [(a, b)] -> ([a], [b])
unzip [FieldPat]
field_pats in
                                             (Pat -> OSet Name) -> [Pat] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pat -> OSet Name
extractBoundNamesPat [Pat]
pats
extractBoundNamesPat (ListP [Pat]
pats)          = (Pat -> OSet Name) -> [Pat] -> OSet Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pat -> OSet Name
extractBoundNamesPat [Pat]
pats
extractBoundNamesPat (SigP Pat
pat Kind
_)          = Pat -> OSet Name
extractBoundNamesPat Pat
pat
extractBoundNamesPat (ViewP Exp
_ Pat
pat)         = Pat -> OSet Name
extractBoundNamesPat Pat
pat
#if __GLASGOW_HASKELL__ >= 801
extractBoundNamesPat (UnboxedSumP Pat
pat Int
_ Int
_) = Pat -> OSet Name
extractBoundNamesPat Pat
pat
#endif
#if __GLASGOW_HASKELL__ >= 909
extractBoundNamesPat (TypeP _)             = OS.empty
extractBoundNamesPat (InvisP _)            = OS.empty
#endif
#if __GLASGOW_HASKELL__ >= 911
extractBoundNamesPat (OrP pats)            = foldMap extractBoundNamesPat pats
#endif

----------------------------------------
-- General utility
----------------------------------------

-- dirty implementation of explicit-to-implicit conversion
newtype MagicIP name a r = MagicIP (IP name a => r)

-- | Get an implicit param constraint (@IP name a@, which is the desugared
-- form of @(?name :: a)@) from an explicit value.
--
-- This function is only available with GHC 8.0 or later.
bindIP :: forall name a r. a -> (IP name a => r) -> r
bindIP :: forall (name :: Symbol) a r. a -> (IP name a => r) -> r
bindIP a
val IP name a => r
k = (MagicIP name a r -> a -> r
forall a b. a -> b
unsafeCoerce (forall (name :: Symbol) a r. (IP name a => r) -> MagicIP name a r
MagicIP @name r
IP name a => r
k) :: a -> r) a
val

-- like GHC's
splitAtList :: [a] -> [b] -> ([b], [b])
splitAtList :: forall a b. [a] -> [b] -> ([b], [b])
splitAtList [] [b]
x = ([], [b]
x)
splitAtList (a
_ : [a]
t) (b
x : [b]
xs) =
  let ([b]
as, [b]
bs) = [a] -> [b] -> ([b], [b])
forall a b. [a] -> [b] -> ([b], [b])
splitAtList [a]
t [b]
xs in
  (b
x b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
as, [b]
bs)
splitAtList (a
_ : [a]
_) [] = ([], [])

thdOf3 :: (a,b,c) -> c
thdOf3 :: forall a b c. (a, b, c) -> c
thdOf3 (a
_,b
_,c
c) = c
c

liftFst :: (a -> b) -> (a, c) -> (b, c)
liftFst :: forall a b c. (a -> b) -> (a, c) -> (b, c)
liftFst a -> b
f (a
a,c
c) = (a -> b
f a
a, c
c)

liftSnd :: (a -> b) -> (c, a) -> (c, b)
liftSnd :: forall a b c. (a -> b) -> (c, a) -> (c, b)
liftSnd a -> b
f (c
c,a
a) = (c
c, a -> b
f a
a)

thirdOf3 :: (a -> b) -> (c, d, a) -> (c, d, b)
thirdOf3 :: forall a b c d. (a -> b) -> (c, d, a) -> (c, d, b)
thirdOf3 a -> b
f (c
c, d
d, a
a) = (c
c, d
d, a -> b
f a
a)

-- lift concatMap into a monad
-- could this be more efficient?
-- | Concatenate the result of a @mapM@
concatMapM :: (Monad monad, Monoid monoid, Traversable t)
           => (a -> monad monoid) -> t a -> monad monoid
concatMapM :: forall (monad :: * -> *) monoid (t :: * -> *) a.
(Monad monad, Monoid monoid, Traversable t) =>
(a -> monad monoid) -> t a -> monad monoid
concatMapM a -> monad monoid
fn t a
list = do
  t monoid
bss <- (a -> monad monoid) -> t a -> monad (t monoid)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> t a -> m (t b)
mapM a -> monad monoid
fn t a
list
  monoid -> monad monoid
forall a. a -> monad a
forall (m :: * -> *) a. Monad m => a -> m a
return (monoid -> monad monoid) -> monoid -> monad monoid
forall a b. (a -> b) -> a -> b
$ t monoid -> monoid
forall m. Monoid m => t m -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold t monoid
bss

-- like GHC's
-- | Monadic version of mapAccumL
mapAccumLM :: Monad m
            => (acc -> x -> m (acc, y)) -- ^ combining function
            -> acc                      -- ^ initial state
            -> [x]                      -- ^ inputs
            -> m (acc, [y])             -- ^ final state, outputs
mapAccumLM :: forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM acc -> x -> m (acc, y)
_ acc
s []     = (acc, [y]) -> m (acc, [y])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (acc
s, [])
mapAccumLM acc -> x -> m (acc, y)
f acc
s (x
x:[x]
xs) = do
    (acc
s1, y
x')  <- acc -> x -> m (acc, y)
f acc
s x
x
    (acc
s2, [y]
xs') <- (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM acc -> x -> m (acc, y)
f acc
s1 [x]
xs
    (acc, [y]) -> m (acc, [y])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return    (acc
s2, y
x' y -> [y] -> [y]
forall a. a -> [a] -> [a]
: [y]
xs')

-- like GHC's
mapMaybeM :: Monad m => (a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM a -> m (Maybe b)
_ [] = [b] -> m [b]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
mapMaybeM a -> m (Maybe b)
f (a
x:[a]
xs) = do
  Maybe b
y <- a -> m (Maybe b)
f a
x
  [b]
ys <- (a -> m (Maybe b)) -> [a] -> m [b]
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM a -> m (Maybe b)
f [a]
xs
  [b] -> m [b]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([b] -> m [b]) -> [b] -> m [b]
forall a b. (a -> b) -> a -> b
$ case Maybe b
y of
    Maybe b
Nothing -> [b]
ys
    Just b
z  -> b
z b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
ys

expectJustM :: Fail.MonadFail m => String -> Maybe a -> m a
expectJustM :: forall (m :: * -> *) a. MonadFail m => String -> Maybe a -> m a
expectJustM String
_   (Just a
x) = a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
expectJustM String
err Maybe a
Nothing  = String -> m a
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail String
err

firstMatch :: (a -> Maybe b) -> [a] -> Maybe b
firstMatch :: forall a b. (a -> Maybe b) -> [a] -> Maybe b
firstMatch a -> Maybe b
f [a]
xs = [b] -> Maybe b
forall a. [a] -> Maybe a
listToMaybe ([b] -> Maybe b) -> [b] -> Maybe b
forall a b. (a -> b) -> a -> b
$ (a -> Maybe b) -> [a] -> [b]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe a -> Maybe b
f [a]
xs

firstMatchM :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
firstMatchM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m (Maybe b)
firstMatchM a -> m (Maybe b)
f [a]
xs = [b] -> Maybe b
forall a. [a] -> Maybe a
listToMaybe ([b] -> Maybe b) -> m [b] -> m (Maybe b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> m (Maybe b)) -> [a] -> m [b]
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM a -> m (Maybe b)
f [a]
xs

-- | Semi-shallow version of 'everywhereM' - does not recurse into children of nodes of type @a@ (only applies the handler to them).
--
-- >>> topEverywhereM (pure . fmap (*10) :: [Integer] -> Identity [Integer]) ([1,2,3] :: [Integer], "foo" :: String)
-- Identity ([10,20,30],"foo")
--
-- >>> everywhereM (mkM (pure . fmap (*10) :: [Integer] -> Identity [Integer])) ([1,2,3] :: [Integer], "foo" :: String)
-- Identity ([10,200,3000],"foo")
topEverywhereM :: (Typeable a, Data b, Monad m) => (a -> m a) -> b -> m b
topEverywhereM :: forall a b (m :: * -> *).
(Typeable a, Data b, Monad m) =>
(a -> m a) -> b -> m b
topEverywhereM a -> m a
handler =
  (forall d. Data d => d -> m d) -> b -> m b
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> a -> m a
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> b -> m b
gmapM ((a -> m a) -> d -> m d
forall a b (m :: * -> *).
(Typeable a, Data b, Monad m) =>
(a -> m a) -> b -> m b
topEverywhereM a -> m a
handler) (b -> m b) -> (a -> m a) -> b -> m b
forall (m :: * -> *) a b.
(Monad m, Typeable a, Typeable b) =>
(a -> m a) -> (b -> m b) -> a -> m a
`extM` a -> m a
handler

-- Checks if a String names a valid Haskell infix data constructor
-- (i.e., does it begin with a colon?).
isInfixDataCon :: String -> Bool
isInfixDataCon :: String -> Bool
isInfixDataCon (Char
':':String
_) = Bool
True
isInfixDataCon String
_ = Bool
False

-- | Returns 'True' if the argument 'Name' is that of 'Kind.Type'
-- (or @*@ or 'Kind.★', to support older GHCs).
isTypeKindName :: Name -> Bool
isTypeKindName :: Name -> Bool
isTypeKindName Name
n = Name
n Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
typeKindName
#if __GLASGOW_HASKELL__ < 805
                || n == starKindName
                || n == uniStarKindName
#endif

-- | The 'Name' of the kind 'Kind.Type'.
-- 2. The kind @*@ on older GHCs.
typeKindName :: Name
typeKindName :: Name
typeKindName = ''Kind.Type

#if __GLASGOW_HASKELL__ < 805
-- | The 'Name' of the kind @*@.
starKindName :: Name
starKindName = ''(Kind.*)

-- | The 'Name' of the kind 'Kind.★'.
uniStarKindName :: Name
uniStarKindName = ''(Kind.★)
#endif

-- | Is a data type or data instance declaration a @newtype@ declaration, a
-- @data@ declaration, or a @type data@ declaration?
data DataFlavor
  = Newtype  -- ^ @newtype@
  | Data     -- ^ @data@
  | TypeData -- ^ @type data@
  deriving (DataFlavor -> DataFlavor -> Bool
(DataFlavor -> DataFlavor -> Bool)
-> (DataFlavor -> DataFlavor -> Bool) -> Eq DataFlavor
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DataFlavor -> DataFlavor -> Bool
== :: DataFlavor -> DataFlavor -> Bool
$c/= :: DataFlavor -> DataFlavor -> Bool
/= :: DataFlavor -> DataFlavor -> Bool
Eq, Int -> DataFlavor -> String -> String
[DataFlavor] -> String -> String
DataFlavor -> String
(Int -> DataFlavor -> String -> String)
-> (DataFlavor -> String)
-> ([DataFlavor] -> String -> String)
-> Show DataFlavor
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> DataFlavor -> String -> String
showsPrec :: Int -> DataFlavor -> String -> String
$cshow :: DataFlavor -> String
show :: DataFlavor -> String
$cshowList :: [DataFlavor] -> String -> String
showList :: [DataFlavor] -> String -> String
Show, Typeable DataFlavor
Typeable DataFlavor =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> DataFlavor -> c DataFlavor)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DataFlavor)
-> (DataFlavor -> Constr)
-> (DataFlavor -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DataFlavor))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DataFlavor))
-> ((forall b. Data b => b -> b) -> DataFlavor -> DataFlavor)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFlavor -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DataFlavor -> r)
-> (forall u. (forall d. Data d => d -> u) -> DataFlavor -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> DataFlavor -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor)
-> Data DataFlavor
DataFlavor -> Constr
DataFlavor -> DataType
(forall b. Data b => b -> b) -> DataFlavor -> DataFlavor
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DataFlavor -> u
forall u. (forall d. Data d => d -> u) -> DataFlavor -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DataFlavor -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DataFlavor -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DataFlavor
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DataFlavor -> c DataFlavor
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DataFlavor)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataFlavor)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DataFlavor -> c DataFlavor
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DataFlavor -> c DataFlavor
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DataFlavor
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DataFlavor
$ctoConstr :: DataFlavor -> Constr
toConstr :: DataFlavor -> Constr
$cdataTypeOf :: DataFlavor -> DataType
dataTypeOf :: DataFlavor -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DataFlavor)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DataFlavor)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataFlavor)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataFlavor)
$cgmapT :: (forall b. Data b => b -> b) -> DataFlavor -> DataFlavor
gmapT :: (forall b. Data b => b -> b) -> DataFlavor -> DataFlavor
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DataFlavor -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DataFlavor -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DataFlavor -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DataFlavor -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DataFlavor -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> DataFlavor -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataFlavor -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DataFlavor -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DataFlavor -> m DataFlavor
Data, (forall x. DataFlavor -> Rep DataFlavor x)
-> (forall x. Rep DataFlavor x -> DataFlavor) -> Generic DataFlavor
forall x. Rep DataFlavor x -> DataFlavor
forall x. DataFlavor -> Rep DataFlavor x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DataFlavor -> Rep DataFlavor x
from :: forall x. DataFlavor -> Rep DataFlavor x
$cto :: forall x. Rep DataFlavor x -> DataFlavor
to :: forall x. Rep DataFlavor x -> DataFlavor
Generic, (forall (m :: * -> *). Quote m => DataFlavor -> m Exp)
-> (forall (m :: * -> *).
    Quote m =>
    DataFlavor -> Code m DataFlavor)
-> Lift DataFlavor
forall t.
(forall (m :: * -> *). Quote m => t -> m Exp)
-> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
forall (m :: * -> *). Quote m => DataFlavor -> m Exp
forall (m :: * -> *). Quote m => DataFlavor -> Code m DataFlavor
$clift :: forall (m :: * -> *). Quote m => DataFlavor -> m Exp
lift :: forall (m :: * -> *). Quote m => DataFlavor -> m Exp
$cliftTyped :: forall (m :: * -> *). Quote m => DataFlavor -> Code m DataFlavor
liftTyped :: forall (m :: * -> *). Quote m => DataFlavor -> Code m DataFlavor
Lift)