packages feed

generic-deriving 1.10.7 → 1.11

raw patch · 5 files changed

+533/−274 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Generics.Deriving.TH: deriveAll0And1WithKindSigs :: Name -> Q [Dec]
- Generics.Deriving.TH: deriveAll0WithKindSigs :: Name -> Q [Dec]
- Generics.Deriving.TH: deriveAll1WithKindSigs :: Name -> Q [Dec]
- Generics.Deriving.TH: deriveRep0WithKindSigs :: Name -> Q [Dec]
- Generics.Deriving.TH: deriveRep1WithKindSigs :: Name -> Q [Dec]
- Generics.Deriving.TH: deriveRepresentable0WithKindSigs :: Name -> Q [Dec]
- Generics.Deriving.TH: deriveRepresentable1WithKindSigs :: Name -> Q [Dec]
+ Generics.Deriving.TH: InlineRep :: RepOptions
+ Generics.Deriving.TH: Options :: RepOptions -> KindSigOptions -> Options
+ Generics.Deriving.TH: TypeSynonymRep :: RepOptions
+ Generics.Deriving.TH: [kindSigOptions] :: Options -> KindSigOptions
+ Generics.Deriving.TH: [repOptions] :: Options -> RepOptions
+ Generics.Deriving.TH: data Options
+ Generics.Deriving.TH: data RepOptions
+ Generics.Deriving.TH: defaultKindSigOptions :: KindSigOptions
+ Generics.Deriving.TH: defaultOptions :: Options
+ Generics.Deriving.TH: defaultRepOptions :: RepOptions
+ Generics.Deriving.TH: deriveAll0And1Options :: Options -> Name -> Q [Dec]
+ Generics.Deriving.TH: deriveAll0Options :: Options -> Name -> Q [Dec]
+ Generics.Deriving.TH: deriveAll1Options :: Options -> Name -> Q [Dec]
+ Generics.Deriving.TH: deriveRep0Options :: KindSigOptions -> Name -> Q [Dec]
+ Generics.Deriving.TH: deriveRep1Options :: KindSigOptions -> Name -> Q [Dec]
+ Generics.Deriving.TH: deriveRepresentable0Options :: Options -> Name -> Q [Dec]
+ Generics.Deriving.TH: deriveRepresentable1Options :: Options -> Name -> Q [Dec]
+ Generics.Deriving.TH: instance GHC.Classes.Eq Generics.Deriving.TH.Options
+ Generics.Deriving.TH: instance GHC.Classes.Eq Generics.Deriving.TH.RepOptions
+ Generics.Deriving.TH: instance GHC.Classes.Ord Generics.Deriving.TH.Options
+ Generics.Deriving.TH: instance GHC.Classes.Ord Generics.Deriving.TH.RepOptions
+ Generics.Deriving.TH: instance GHC.Read.Read Generics.Deriving.TH.Options
+ Generics.Deriving.TH: instance GHC.Read.Read Generics.Deriving.TH.RepOptions
+ Generics.Deriving.TH: instance GHC.Show.Show Generics.Deriving.TH.Options
+ Generics.Deriving.TH: instance GHC.Show.Show Generics.Deriving.TH.RepOptions
+ Generics.Deriving.TH: makeRep0Inline :: Name -> Q Type -> Q Type
+ Generics.Deriving.TH: makeRep1Inline :: Name -> Q Type -> Q Type
+ Generics.Deriving.TH: type KindSigOptions = Bool

Files

CHANGELOG.md view
@@ -1,3 +1,46 @@+# 1.11+* The behavior of function in `Generics.Deriving.TH` has changed with respect+  to when type synonyms are generated for `Rep(1)` definitions. In particular:++  * By default, `deriveRepresentable(1)` will no longer define its `Rep(1)`+    type family instance in terms of the type synonym that has to be generated+    with `deriveRep(1)`. Similarly, `deriveAll(1)` and `deriveAll0And1` will no+    longer generate a type synonym. Instead, they will generate `Generic(1)`+    instances that directly define the `Rep(1)` instance inline. If you wish+    to revert to the old behavior, you will need to use the variants of those+    functions suffixed with `-Options`.+  * New functions `makeRep0Inline` and `makeRep1Inline` have been added which,+    for most purposes, should replace uses of `makeRep0`/`makeRep0FromType`+    and `makeRep1`/`makeRep1FromType` (but see the next bullet point for a+    caveat).+  * The use of `deriveRep(1)`, `makeRep0`/`makeRep0FromType`, and+    `makeRep1`/`makeRep1FromType` are now discouraged, but those functions are+    still available. The reason is that on GHC 7.0/7.2/7.4, it is impossible to use+    `makeRep0Inline`/`makeRep1Inline` due to a GHC bug. Therefore, you must use+    `makeRep0`/`makeRep1` and `deriveRep(1)` on GHC 7.0/7.2/7.4 out of necessity.++  These changes make dealing with `Generic` instances that involve `PolyKinds`+  and `TypeInType` much easier.+* All functions suffixed in `-WithKindSigs` in `Generics.Deriving.TH` have been+  removed in favor of a more sensible `-Options` suffixing scheme. The ability to+  toggle whether explicit kind signatures are used on type variable binders has+  been folded into `KindSigOptions`, which is an explicit argument to+  `deriveRep0Options`/`deriveRep1Options` and also a field in the more general+  'Options' data type.+* Furthermore, the behavior of derived instances' kind signatures has changed.+  By default, the TH code will now _always_ use explicit kind signatures+  whenever possible, regardless of whether you're working with plain data types+  or data family instances. This makes working with `TypeInType` less+  surprising, but at the cost of making it slightly more awkward to work with+  derived `Generic1` instances that constrain kinds to `*` by means of `(:.:)`.+* Since `Generic1` is polykinded on GHC 8.2 and later, the functions in+  `Generics.Deriving.TH` will no longer unify the kind of the last type+  parameter to be `*`.+* Fix a bug in which `makeRep` (and similarly named functions) would not check+  whether the argument type can actually have a well kinded `Generic(1)`+  instance.+* Backport missing `Foldable` and `Traversable` instances for `Rec1`+ # 1.10.7 * Renamed internal modules to avoid using apostrophes (averting this bug:   https://github.com/haskell/cabal/issues/3631)
generic-deriving.cabal view
@@ -1,5 +1,5 @@ name:                   generic-deriving-version:                1.10.7+version:                1.11 synopsis:               Generic programming library for generalised deriving. description: @@ -12,7 +12,7 @@   .   The current implementation integrates with the new GHC Generics. See   <http://www.haskell.org/haskellwiki/GHC.Generics> for more information.-  Template Haskell code is provided for supporting GHC before version 7.2.+  Template Haskell code is provided for supporting older GHCs.  homepage:               https://github.com/dreixel/generic-deriving bug-reports:            https://github.com/dreixel/generic-deriving/issues
src/Generics/Deriving/Base/Internal.hs view
@@ -729,7 +729,7 @@  -- | Recursive calls of kind * -> * newtype Rec1 f p = Rec1 { unRec1 :: f p }-  deriving (Eq, Ord, Read, Functor, Show)+  deriving (Eq, Ord, Read, Functor, Foldable, Traversable, Show)  instance Applicative f => Applicative (Rec1 f) where   pure a = Rec1 (pure a)
src/Generics/Deriving/TH.hs view
@@ -43,7 +43,7 @@  -- Adapted from Generics.Regular.TH module Generics.Deriving.TH (-+      -- * @derive@- functions       deriveMeta     , deriveData     , deriveConstructors@@ -58,27 +58,40 @@     , deriveRep0     , deriveRep1     , simplInstance-     -- * -@WithSigs@ functions-     -- $withSigs-    , deriveAll0WithKindSigs-    , deriveAll1WithKindSigs-    , deriveAll0And1WithKindSigs-    , deriveRepresentable0WithKindSigs-    , deriveRepresentable1WithKindSigs-    , deriveRep0WithKindSigs-    , deriveRep1WithKindSigs+      -- * @make@- functions      -- $make+    , makeRep0Inline     , makeRep0     , makeRep0FromType     , makeFrom     , makeFrom0     , makeTo     , makeTo0+    , makeRep1Inline     , makeRep1     , makeRep1FromType     , makeFrom1     , makeTo1++     -- * Options+     -- $options+     -- ** Option types+    , Options(..)+    , defaultOptions+    , RepOptions(..)+    , defaultRepOptions+    , KindSigOptions+    , defaultKindSigOptions++    -- ** Functions with optional arguments+    , deriveAll0Options+    , deriveAll1Options+    , deriveAll0And1Options+    , deriveRepresentable0Options+    , deriveRepresentable1Options+    , deriveRep0Options+    , deriveRep1Options   ) where  import           Control.Monad ((>=>), unless, when)@@ -88,6 +101,7 @@ #endif import           Data.List (nub) import qualified Data.Map as Map (fromList)+import           Data.Maybe (catMaybes)  import           Generics.Deriving.TH.Internal #if MIN_VERSION_base(4,9,0)@@ -99,33 +113,26 @@ import           Language.Haskell.TH.Lib import           Language.Haskell.TH -{- $withSigs-By default, 'deriveRep0', 'deriveRep1', and functions that invoke it generate-type synonyms whose type variable binders do not have explicit kind binders for-polykinded type variables. This is a pretty reasonable default, since puts less-of a burden on the Template Haskell machinery to get the kinds just right, and-lets the kind inferencer do more work. However, there are times when you want to-have explicit kind signatures, such as if you have a datatype that uses-@-XTypeInType@. For example:--@-data Prox (a :: k) (b :: *) = Prox k-$('deriveRep0WithKindSigs' ''Prox)-@--will result in something like:--@-type Rep0Prox (a :: k) (b :: *) = Rec0 k-@+{- $options+'Options' gives you a way to further tweak derived 'Generic' and 'Generic1' instances: -Whereas if you had used 'deriveRep0', you would have something like:+* 'RepOptions': By default, all derived 'Rep' and 'Rep1' type instances emit the code+  directly (the 'InlineRep' option). One can also choose to emit a separate type+  synonym for the 'Rep' type (this is the functionality of 'deriveRep0' and+  'deriveRep1') and define a 'Rep' instance in terms of that type synonym (the+  'TypeSynonymRep' option). -@-type Rep0Prox a (b :: *) = Rec0 k-@+* 'KindSigOptions': By default, all derived instances will use explicit kind+  signatures (when the 'KindSigOptions' is 'True'). You might wish to set the+  'KindSigOptions' to 'False' if you want a 'Generic'/'Generic1' instance at+  a particular kind that GHC will infer correctly, but the functions in this+  module won't guess correctly. For example, the following example will only+  compile with 'KindSigOptions' set to 'False': -which will fail to compile, since k is out-of-scope!+  @+  newtype Compose (f :: k2 -> *) (g :: k1 -> k2) (a :: k1) = Compose (f (g a))+  $('deriveAll1Options' False ''Compose)+  @ -}  -- | Given the names of a generic class, a type to instantiate, a function in@@ -140,6 +147,39 @@     [funD fn [clause [] (normalB (varE df `appE`       (sigE (varE undefinedValName) (return typ)))) []]] +-- | Additional options for configuring derived 'Generic'/'Generic1' instances+-- using Template Haskell.+data Options = Options+  { repOptions     :: RepOptions+  , kindSigOptions :: KindSigOptions+  } deriving (Eq, Ord, Read, Show)++-- | Sensible default 'Options' ('defaultRepOptions' and 'defaultKindSigOptions').+defaultOptions :: Options+defaultOptions = Options+  { repOptions     = defaultRepOptions+  , kindSigOptions = defaultKindSigOptions+  }++-- | Configures whether 'Rep'/'Rep1' type instances should be defined inline in a+-- derived 'Generic'/'Generic1' instance ('InlineRep') or defined in terms of a+-- type synonym ('TypeSynonymRep').+data RepOptions = InlineRep+                | TypeSynonymRep+  deriving (Eq, Ord, Read, Show)++-- | 'InlineRep', a sensible default 'RepOptions'.+defaultRepOptions :: RepOptions+defaultRepOptions = InlineRep++-- | 'True' if explicit kind signatures should be used in derived+-- 'Generic'/'Generic1' instances, 'False' otherwise.+type KindSigOptions = Bool++-- | 'True', a sensible default 'KindSigOptions'.+defaultKindSigOptions :: KindSigOptions+defaultKindSigOptions = True+ -- | A backwards-compatible synonym for 'deriveAll0'. deriveAll :: Name -> Q [Dec] deriveAll = deriveAll0@@ -148,134 +188,133 @@ -- generate the 'Data' instance, the 'Constructor' instances, the 'Selector' -- instances, and the 'Representable0' instance. deriveAll0 :: Name -> Q [Dec]-deriveAll0 = deriveAllCommon True False False+deriveAll0 = deriveAll0Options defaultOptions --- | Like 'deriveAll0', except that the type variable binders in the--- 'Rep' type synonym will have explicit kind signatures.-deriveAll0WithKindSigs :: Name -> Q [Dec]-deriveAll0WithKindSigs = deriveAllCommon True False True+-- | Like 'deriveAll0', but takes an 'Options' argument.+deriveAll0Options :: Options -> Name -> Q [Dec]+deriveAll0Options = deriveAllCommon True False  -- | Given the type and the name (as string) for the type to derive, -- generate the 'Data' instance, the 'Constructor' instances, the 'Selector' -- instances, and the 'Representable1' instance. deriveAll1 :: Name -> Q [Dec]-deriveAll1 = deriveAllCommon False True False+deriveAll1 = deriveAll1Options defaultOptions --- | Like 'deriveAll1', except that the type variable binders in the--- 'Rep1' type synonym will have explicit kind signatures.-deriveAll1WithKindSigs :: Name -> Q [Dec]-deriveAll1WithKindSigs = deriveAllCommon False True True+-- | Like 'deriveAll1', but takes an 'Options' argument.+deriveAll1Options :: Options -> Name -> Q [Dec]+deriveAll1Options = deriveAllCommon False True  -- | Given the type and the name (as string) for the type to derive, -- generate the 'Data' instance, the 'Constructor' instances, the 'Selector' -- instances, the 'Representable0' instance, and the 'Representable1' instance. deriveAll0And1 :: Name -> Q [Dec]-deriveAll0And1 = deriveAllCommon True True False+deriveAll0And1 = deriveAll0And1Options defaultOptions --- | Like 'deriveAll0And1', except that the type variable binders in the--- 'Rep' and 'Rep1' type synonyms will have explicit kind signatures.-deriveAll0And1WithKindSigs :: Name -> Q [Dec]-deriveAll0And1WithKindSigs = deriveAllCommon True True True+-- | Like 'deriveAll0And1', but takes an 'Options' argument.+deriveAll0And1Options :: Options -> Name -> Q [Dec]+deriveAll0And1Options = deriveAllCommon True True -deriveAllCommon :: Bool -> Bool -> Bool -> Name -> Q [Dec]-deriveAllCommon generic generic1 useKindSigs n = do+deriveAllCommon :: Bool -> Bool -> Options -> Name -> Q [Dec]+deriveAllCommon generic generic1 opts n = do     a <- deriveMeta n     b <- if generic-            then deriveRepresentableCommon Generic useKindSigs n+            then deriveRepresentableCommon Generic opts n             else return []     c <- if generic1-            then deriveRepresentableCommon Generic1 useKindSigs n+            then deriveRepresentableCommon Generic1 opts n             else return []     return (a ++ b ++ c)  -- | Given the type and the name (as string) for the Representable0 type -- synonym to derive, generate the 'Representable0' instance. deriveRepresentable0 :: Name -> Q [Dec]-deriveRepresentable0 = deriveRepresentableCommon Generic False+deriveRepresentable0 = deriveRepresentable0Options defaultOptions --- | Like 'deriveRepresentable0', except that the type variable binders in the--- 'Rep' type synonym will have explicit kind signatures.-deriveRepresentable0WithKindSigs :: Name -> Q [Dec]-deriveRepresentable0WithKindSigs = deriveRepresentableCommon Generic True+-- | Like 'deriveRepresentable0', but takes an 'Options' argument.+deriveRepresentable0Options :: Options -> Name -> Q [Dec]+deriveRepresentable0Options = deriveRepresentableCommon Generic  -- | Given the type and the name (as string) for the Representable1 type -- synonym to derive, generate the 'Representable1' instance. deriveRepresentable1 :: Name -> Q [Dec]-deriveRepresentable1 = deriveRepresentableCommon Generic1 False+deriveRepresentable1 = deriveRepresentable1Options defaultOptions --- | Like 'deriveRepresentable1', except that the type variable binders in the--- 'Rep1' type synonym will have explicit kind signatures.-deriveRepresentable1WithKindSigs :: Name -> Q [Dec]-deriveRepresentable1WithKindSigs = deriveRepresentableCommon Generic1 True+-- | Like 'deriveRepresentable1', but takes an 'Options' argument.+deriveRepresentable1Options :: Options -> Name -> Q [Dec]+deriveRepresentable1Options = deriveRepresentableCommon Generic1 -deriveRepresentableCommon :: GenericClass -> Bool -> Name -> Q [Dec]-deriveRepresentableCommon gClass useKindSigs n = do-    rep  <- deriveRepCommon gClass useKindSigs n-    inst <- deriveInst gClass n+deriveRepresentableCommon :: GenericClass -> Options -> Name -> Q [Dec]+deriveRepresentableCommon gClass opts n = do+    rep  <- if repOptions opts == InlineRep+               then return []+               else deriveRepCommon gClass (kindSigOptions opts) n+    inst <- deriveInst gClass opts n     return (rep ++ inst)  -- | Derive only the 'Rep0' type synonym. Not needed if 'deriveRepresentable0' -- is used. deriveRep0 :: Name -> Q [Dec]-deriveRep0 = deriveRepCommon Generic False+deriveRep0 = deriveRep0Options defaultKindSigOptions --- | Like 'deriveRep0', except that the type variable binders in the 'Rep'--- type synonym will have explicit kind signatures.-deriveRep0WithKindSigs :: Name -> Q [Dec]-deriveRep0WithKindSigs = deriveRepCommon Generic True+-- | Like 'deriveRep0', but takes an 'KindSigOptions' argument.+deriveRep0Options :: KindSigOptions -> Name -> Q [Dec]+deriveRep0Options = deriveRepCommon Generic  -- | Derive only the 'Rep1' type synonym. Not needed if 'deriveRepresentable1' -- is used. deriveRep1 :: Name -> Q [Dec]-deriveRep1 = deriveRepCommon Generic1 False+deriveRep1 = deriveRep1Options defaultKindSigOptions --- | Like 'deriveRep1', except that the type variable binders in the 'Rep1'--- type synonym will have explicit kind signatures.-deriveRep1WithKindSigs :: Name -> Q [Dec]-deriveRep1WithKindSigs = deriveRepCommon Generic1 True+-- | Like 'deriveRep1', but takes an 'KindSigOptions' argument.+deriveRep1Options :: KindSigOptions -> Name -> Q [Dec]+deriveRep1Options = deriveRepCommon Generic1 -deriveRepCommon :: GenericClass -> Bool -> Name -> Q [Dec]+deriveRepCommon :: GenericClass -> KindSigOptions -> Name -> Q [Dec] deriveRepCommon gClass useKindSigs n = do   i <- reifyDataInfo n   let (name, isNT, declTvbs, cons, dv) = either error id i   -- See Note [Forcing buildTypeInstance]-  !_ <- buildTypeInstance gClass name declTvbs dv+  !_ <- buildTypeInstance gClass useKindSigs name declTvbs dv+  tySynVars <- grabTyVarsFromCons gClass cons -  tySynTvbs <- grabTyVarBndrsFromCons gClass cons-  let tySynTvbs' = if useKindSigs-                      then tySynTvbs-                      else map (\tvb -> if isKindMonomorphic (tyVarBndrKind tvb)-                                           then tvb-                                           else unKindedTV tvb) tySynTvbs+  -- See Note [Kind signatures in derived instances]+  let tySynVars' = if useKindSigs+                      then tySynVars+                      else map unSigT tySynVars   fmap (:[]) $ tySynD (genRepName gClass dv name)-                      tySynTvbs'-                      -- The typechecker will infer the kinds of the TyVarBndrs-                      -- in a type synonym declaration, so we don't need to-                      -- splice them in explicitly (hence the unKindedTV call).-                      (repType gClass dv name isNT cons tySynTvbs)+                      (catMaybes $ map typeToTyVarBndr tySynVars')+                      (repType gClass dv name isNT cons tySynVars) -deriveInst :: GenericClass -> Name -> Q [Dec]+deriveInst :: GenericClass -> Options -> Name -> Q [Dec] deriveInst Generic  = deriveInstCommon genericTypeName  repTypeName  Generic  fromValName  toValName deriveInst Generic1 = deriveInstCommon generic1TypeName rep1TypeName Generic1 from1ValName to1ValName -deriveInstCommon :: Name -> Name -> GenericClass -> Name -> Name -> Name -> Q [Dec]-deriveInstCommon genericName repName gClass fromName toName n = do+deriveInstCommon :: Name -> Name -> GenericClass -> Name -> Name -> Options -> Name -> Q [Dec]+deriveInstCommon genericName repName gClass fromName toName opts n = do   i <- reifyDataInfo n-  let (name, _, allTvbs, cons, dv) = either error id i-  origTy      <- buildTypeInstance gClass name allTvbs dv-  repTySynApp <- makeRepTySynApp gClass dv name cons origTy-  let tyIns = TySynInstD repName+  let (name, isNT, allTvbs, cons, dv) = either error id i+      useKindSigs = kindSigOptions opts+  -- See Note [Forcing buildTypeInstance]+  !(origTy, origKind) <- buildTypeInstance gClass useKindSigs name allTvbs dv+  tyInsRHS <- if repOptions opts == InlineRep+                 then makeRepInline   gClass dv name isNT cons origTy+                 else makeRepTySynApp gClass dv name      cons origTy++  let origSigTy = if useKindSigs+                     then SigT origTy origKind+                     else origTy+      tyIns = TySynInstD repName #if MIN_VERSION_template_haskell(2,9,0)-                         (TySynEqn [origTy] repTySynApp)+                         (TySynEqn [origSigTy] tyInsRHS) #else-                         [origTy] repTySynApp+                         [origSigTy] tyInsRHS #endif       mkBody maker = [clause [] (normalB $ mkCaseExp gClass name cons maker) []]       fcs = mkBody mkFrom       tcs = mkBody mkTo    fmap (:[]) $-    instanceD (cxt []) (conT genericName `appT` return origTy)+    instanceD (cxt []) (conT genericName `appT` return origSigTy)                          [return tyIns, funD fromName fcs, funD toName tcs]  {- $make@@ -285,7 +324,7 @@ 'Generic1' instances. As an example, consider this data type:  @-data Fix f a = Fix (f (Fix f a))+newtype Fix f a = Fix (f (Fix f a)) @  A proper 'Generic1' instance would look like this:@@ -302,16 +341,16 @@ $('deriveMeta' ''Fix) $('deriveRep1' ''Fix) instance Functor f => Generic1 (Fix f) where-  type Rep1 (Fix f) = $('makeRep1FromType' ''Fix [t| Fix f |])+  type Rep1 (Fix f) = $('makeRep1Inline' ''Fix [t| Fix f |])   from1 = $('makeFrom1' ''Fix)   to1   = $('makeTo1'   ''Fix) @  Note that due to the lack of type-level lambdas in Haskell, one must manually-apply @'makeRep1FromType' ''Fix@ to the type @Fix f@.+apply @'makeRep1Inline' ''Fix@ to the type @Fix f@.  Be aware that there is a bug on GHC 7.0, 7.2, and 7.4 which might prevent you from-using 'makeRep0FromType' and 'makeRep1FromType'. In the @Fix@ example above, you+using 'makeRep0Inline' and 'makeRep1Inline'. In the @Fix@ example above, you would experience the following error:  @@@ -319,11 +358,16 @@     In the Template Haskell quotation [t| Fix f |] @ -Then a workaround is to use 'makeRep1' instead, which requires you to pass as-arguments the type variables that occur in the instance, in order from left to-right, excluding duplicates. (Normally, 'makeRep1FromType' would figure this-out for you.) Using the above example:+Then a workaround is to use 'makeRep1' instead, which requires you to: +1. Invoke 'deriveRep1' beforehand++2. Pass as arguments the type variables that occur in the instance, in order+   from left to right, topologically sorted, excluding duplicates. (Normally,+   'makeRep1Inline' would figure this out for you.)++Using the above example:+ @ $('deriveMeta' ''Fix) $('deriveRep1' ''Fix)@@ -351,6 +395,40 @@ Note that you don't pass @b@ twice, only once. -} +-- | Generates the full 'Rep' type inline. Since this type can be quite+-- large, it is recommended you only use this to define 'Rep', e.g.,+--+-- @+-- type Rep (Foo (a :: k) b) = $('makeRep0Inline' ''Foo [t| Foo (a :: k) b |])+-- @+--+-- You can then simply refer to @Rep (Foo a b)@ elsewhere.+--+-- Note that the type passed as an argument to 'makeRep0Inline' must match the+-- type argument of 'Rep' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep0Inline' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+makeRep0Inline :: Name -> Q Type -> Q Type+makeRep0Inline n = makeRepCommon Generic InlineRep n . Just++-- | Generates the full 'Rep1' type inline. Since this type can be quite+-- large, it is recommended you only use this to define 'Rep1', e.g.,+--+-- @+-- type Rep1 (Foo (a :: k)) = $('makeRep0Inline' ''Foo [t| Foo (a :: k) |])+-- @+--+-- You can then simply refer to @Rep1 (Foo a)@ elsewhere.+--+-- Note that the type passed as an argument to 'makeRep1Inline' must match the+-- type argument of 'Rep1' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep1Inline' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+makeRep1Inline :: Name -> Q Type -> Q Type+makeRep1Inline n = makeRepCommon Generic1 InlineRep n . Just+ -- | Generates the 'Rep' type synonym constructor (as opposed to 'deriveRep0', -- which generates the type synonym declaration). After splicing it into -- Haskell source, it expects types as arguments. For example:@@ -358,52 +436,99 @@ -- @ -- type Rep (Foo a b) = $('makeRep0' ''Foo) a b -- @+--+-- The use of 'makeRep0' is generally discouraged, as it can sometimes be+-- difficult to predict the order in which you are expected to pass type+-- variables. As a result, 'makeRep0Inline' is recommended instead. However,+-- 'makeRep0Inline' is not usable on GHC 7.0, 7.2, or 7.4 due to a GHC bug,+-- so 'makeRep0' still exists for GHC 7.0, 7.2, and 7.4 users. makeRep0 :: Name -> Q Type-makeRep0 n = makeRepCommon Generic n Nothing+makeRep0 n = makeRepCommon Generic TypeSynonymRep n Nothing  -- | Generates the 'Rep1' type synonym constructor (as opposed to 'deriveRep1', -- which generates the type synonym declaration). After splicing it into -- Haskell source, it expects types as arguments. For example: -- -- @--- type Rep1 (Foo a b) = $('makeRep1' ''Foo) a b+-- type Rep1 (Foo a) = $('makeRep1' ''Foo) a -- @+--+-- The use of 'makeRep1' is generally discouraged, as it can sometimes be+-- difficult to predict the order in which you are expected to pass type+-- variables. As a result, 'makeRep1Inline' is recommended instead. However,+-- 'makeRep1Inline' is not usable on GHC 7.0, 7.2, or 7.4 due to a GHC bug,+-- so 'makeRep1' still exists for GHC 7.0, 7.2, and 7.4 users. makeRep1 :: Name -> Q Type-makeRep1 n = makeRepCommon Generic1 n Nothing+makeRep1 n = makeRepCommon Generic1 TypeSynonymRep n Nothing  -- | Generates the 'Rep' type synonym constructor (as opposed to 'deriveRep0', -- which generates the type synonym declaration) applied to its type arguments. -- Unlike 'makeRep0', this also takes a quoted 'Type' as an argument, e.g., -- -- @--- type Rep (Foo a b) = $('makeRep0FromType' ''Foo [t| Foo a b |])+-- type Rep (Foo (a :: k) b) = $('makeRep0FromType' ''Foo [t| Foo (a :: k) b |]) -- @+--+-- Note that the type passed as an argument to 'makeRep0FromType' must match the+-- type argument of 'Rep' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep0FromType' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+--+-- The use of 'makeRep0FromType' is generally discouraged, since 'makeRep0Inline'+-- does exactly the same thing but without having to go through an intermediate+-- type synonym, and as a result, 'makeRep0Inline' tends to be less buggy. makeRep0FromType :: Name -> Q Type -> Q Type-makeRep0FromType n = makeRepCommon Generic n . Just+makeRep0FromType n = makeRepCommon Generic TypeSynonymRep n . Just  -- | Generates the 'Rep1' type synonym constructor (as opposed to 'deriveRep1', -- which generates the type synonym declaration) applied to its type arguments. -- Unlike 'makeRep1', this also takes a quoted 'Type' as an argument, e.g., -- -- @--- type Rep1 (Foo a b) = $('makeRep1FromType' ''Foo [t| Foo a b |])+-- type Rep1 (Foo (a :: k)) = $('makeRep1FromType' ''Foo [t| Foo (a :: k) |]) -- @+--+-- Note that the type passed as an argument to 'makeRep1FromType' must match the+-- type argument of 'Rep' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep1FromType' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+--+-- The use of 'makeRep1FromType' is generally discouraged, since 'makeRep1Inline'+-- does exactly the same thing but without having to go through an intermediate+-- type synonym, and as a result, 'makeRep1Inline' tends to be less buggy. makeRep1FromType :: Name -> Q Type -> Q Type-makeRep1FromType n = makeRepCommon Generic1 n . Just+makeRep1FromType n = makeRepCommon Generic1 TypeSynonymRep n . Just  makeRepCommon :: GenericClass+              -> RepOptions               -> Name               -> Maybe (Q Type)               -> Q Type-makeRepCommon gClass n mbQTy = do+makeRepCommon gClass repOpts n mbQTy = do   i <- reifyDataInfo n-  let (name, _, _, cons, dv) = either error id i-  case mbQTy of-       Just qTy -> do-           ty <- qTy-           makeRepTySynApp gClass dv name cons ty-       Nothing -> conT $ genRepName gClass dv name+  let (name, isNT, declTvbs, cons, dv) = either error id i+  -- See Note [Forcing buildTypeInstance]+  !_ <- buildTypeInstance gClass False name declTvbs dv +  case (mbQTy, repOpts) of+       (Just qTy, TypeSynonymRep) -> qTy >>= makeRepTySynApp gClass dv name cons+       (Just qTy, InlineRep)      -> qTy >>= makeRepInline   gClass dv name isNT cons+       (Nothing,  TypeSynonymRep) -> conT $ genRepName gClass dv name+       (Nothing,  InlineRep)      -> fail "makeRepCommon"++makeRepInline :: GenericClass+              -> DataVariety+              -> Name+              -> Bool+              -> [Con]+              -> Type+              -> Q Type+makeRepInline gClass dv name isNT cons ty = do+  let instVars = map tyVarBndrToType $ tyVarsOfType ty+  repType gClass dv name isNT cons instVars+ makeRepTySynApp :: GenericClass                 -> DataVariety                 -> Name@@ -415,15 +540,15 @@   -- of the LHS of the Rep(1) instance. We call unKindedTV because the kind   -- inferencer can figure out the kinds perfectly well, so we don't need to   -- give anything here explicit kind signatures.-  let instTvbs = nub . map unKindedTV $ visibleTyVarsOfType ty+  let instTvbs = nub . map unKindedTV $ requiredTyVarsOfType ty   -- We grab the type variables from the first constructor's type signature.   -- Or, if there are no constructors, we grab no type variables. The latter   -- is okay because we use zipWith to ensure that we never pass more type   -- variables than the generated type synonym can accept.   -- See Note [Arguments to generated type synonyms]-  tySynTvbs <- grabTyVarBndrsFromCons gClass cons+  tySynVars <- grabTyVarsFromCons gClass cons   return . applyTyToTvbs (genRepName gClass dv name)-         $ zipWith const instTvbs tySynTvbs+         $ zipWith const instTvbs tySynVars  -- | A backwards-compatible synonym for 'makeFrom0'. makeFrom :: Name -> Q Exp@@ -455,7 +580,7 @@   i <- reifyDataInfo n   let (name, _, allTvbs, cons, dv) = either error id i   -- See Note [Forcing buildTypeInstance]-  buildTypeInstance gClass name allTvbs dv+  buildTypeInstance gClass False name allTvbs dv     `seq` mkCaseExp gClass name cons maker  genRepName :: GenericClass -> DataVariety -> Name -> Name@@ -471,12 +596,12 @@         -> Name         -> Bool         -> [Con]-        -> [TyVarBndr]+        -> [Type]         -> Q Type-repType gClass dv dt isNT cs tySynTvbs =+repType gClass dv dt isNT cs tySynVars =     conT d1TypeName `appT` mkMetaDataType dv dt isNT `appT`       foldr1' sum' (conT v1TypeName)-        (map (repCon gClass dv dt tySynTvbs) cs)+        (map (repCon gClass dv dt tySynVars) cs)   where     sum' :: Q Type -> Q Type -> Q Type     sum' a b = conT sumTypeName `appT` a `appT` b@@ -484,35 +609,35 @@ repCon :: GenericClass        -> DataVariety        -> Name-       -> [TyVarBndr]+       -> [Type]        -> Con        -> Q Type-repCon gClass dv dt tySynTvbs (NormalC n bts) = do+repCon gClass dv dt tySynVars (NormalC n bts) = do     let bangs = map fst bts     ssis <- reifySelStrictInfo n bangs-    repConWith gClass dv dt n tySynTvbs Nothing ssis False False-repCon gClass dv dt tySynTvbs (RecC n vbts) = do+    repConWith gClass dv dt n tySynVars Nothing ssis False False+repCon gClass dv dt tySynVars (RecC n vbts) = do     let (selNames, bangs, _) = unzip3 vbts     ssis <- reifySelStrictInfo n bangs-    repConWith gClass dv dt n tySynTvbs (Just selNames) ssis True False-repCon gClass dv dt tySynTvbs (InfixC t1 n t2) = do+    repConWith gClass dv dt n tySynVars (Just selNames) ssis True False+repCon gClass dv dt tySynVars (InfixC t1 n t2) = do     let bangs = map fst [t1, t2]     ssis <- reifySelStrictInfo n bangs-    repConWith gClass dv dt n tySynTvbs Nothing ssis False True+    repConWith gClass dv dt n tySynVars Nothing ssis False True repCon _ _ _ _ con = gadtError con  repConWith :: GenericClass            -> DataVariety            -> Name            -> Name-           -> [TyVarBndr]+           -> [Type]            -> Maybe [Name]            -> [SelStrictInfo]            -> Bool            -> Bool            -> Q Type-repConWith gClass dv dt n tySynTvbs mbSelNames ssis isRecord isInfix = do-    (conTvbs, ts, gk) <- reifyConTys gClass n+repConWith gClass dv dt n tySynVars mbSelNames ssis isRecord isInfix = do+    (conVars, ts, gk) <- reifyConTys gClass n      let structureType :: Q Type         structureType = case ssis of@@ -522,8 +647,8 @@         -- See Note [Substituting types in a constructor type signature]         typeSubst :: TypeSubst         typeSubst = Map.fromList $-          zip (concatMap             tyVarNamesOfTyVarBndr  conTvbs)-              (concatMap (map VarT . tyVarNamesOfTyVarBndr) tySynTvbs)+          zip (concatMap             tyVarNamesOfType  conVars)+              (concatMap (map VarT . tyVarNamesOfType) tySynVars)          f :: [Q Type]         f = case mbSelNames of@@ -556,7 +681,13 @@     -- See Note [Substituting types in constructor type signatures]     t', t'' :: Type     t' = case gk of-              Gen1 _ (Just kvName) -> substNameWithKind kvName starK t+              Gen1 _ (Just _kvName) ->+-- See Note [Generic1 is polykinded on GHC 8.2]+#if __GLASGOW_HASKELL__ >= 801+                t+#else+                substNameWithKind _kvName starK t+#endif               _ -> t     t'' = substType typeSubst t' @@ -805,9 +936,11 @@   | ty == ConT wordHashTypeName   = Just (uWordTypeName,   uWordDataName,   uWordHashValName)   | otherwise                     = Nothing --- | Deduces the instance type to use for a Generic(1) instance.+-- | Deduces the instance type (and kind) to use for a Generic(1) instance. buildTypeInstance :: GenericClass                   -- ^ Generic or Generic1+                  -> KindSigOptions+                  -- ^ Whether or not to use explicit kind signatures in the instance type                   -> Name                   -- ^ The type constructor or data family name                   -> [TyVarBndr]@@ -815,17 +948,17 @@                   -> DataVariety                   -- ^ If using a data family instance, provides the types used                   -- to instantiate the instance-                  -> Q Type+                  -> Q (Type, Kind) -- Plain data type/newtype case-buildTypeInstance gClass tyConName tvbs DataPlain =+buildTypeInstance gClass useKindSigs tyConName tvbs DataPlain =     let varTys :: [Type]         varTys = map tyVarBndrToType tvbs-    in buildTypeInstanceFromTys gClass tyConName varTys False+    in buildTypeInstanceFromTys gClass useKindSigs tyConName varTys -- Data family instance case -- -- The CPP is present to work around a couple of annoying old GHC bugs. -- See Note [Polykinded data families in Template Haskell]-buildTypeInstance gClass parentName tvbs (DataFamily _ instTysAndKinds) = do+buildTypeInstance gClass useKindSigs parentName tvbs (DataFamily _ instTysAndKinds) = do #if !(MIN_VERSION_template_haskell(2,8,0)) || MIN_VERSION_template_haskell(2,10,0)     let instTys :: [Type]         instTys = zipWith stealKindForType tvbs instTysAndKinds@@ -860,11 +993,11 @@     xTypeNames <- newNameList "tExtra" (length tvbs - length givenTys)      let xTys   :: [Type]+        -- Because these type variables were eta-reduced away, we can only+        -- determine their kind by using stealKindForType. Therefore, we mark+        -- them as VarT to ensure they will be given an explicit kind annotation+        -- (and so the kind inference machinery has the right information).         xTys = map VarT xTypeNames-        -- ^ Because these type variables were eta-reduced away, we can only-        --   determine their kind by using stealKindForType. Therefore, we mark-        --   them as VarT to ensure they will be given an explicit kind annotation-        --   (and so the kind inference machinery has the right information).          substNamesWithKinds :: [(Name, Kind)] -> Type -> Type         substNamesWithKinds nks t = foldr' (uncurry substNameWithKind) t nks@@ -884,22 +1017,23 @@                   -- grab the correct kind.                 $ zipWith stealKindForType tvbs (givenTys ++ xTys) #endif-    buildTypeInstanceFromTys gClass parentName instTys True+    buildTypeInstanceFromTys gClass useKindSigs parentName instTys --- For the given Types, deduces the instance type to use for a Generic(1) instance.--- Coming up with the instance type isn't as simple as dropping the last types, as--- you need to be wary of kinds being instantiated with *.+-- For the given Types, deduces the instance type (and kind) to use for a+-- Generic(1) instance. Coming up with the instance type isn't as simple as+-- dropping the last types, as you need to be wary of kinds being instantiated+-- with *. -- See Note [Type inference in derived instances] buildTypeInstanceFromTys :: GenericClass                          -- ^ Generic or Generic1+                         -> KindSigOptions+                         -- ^ Whether or not to use explicit kind signatures in the instance type                          -> Name                          -- ^ The type constructor or data family name                          -> [Type]                          -- ^ The types to instantiate the instance with-                         -> Bool-                         -- ^ True if it's a data family, False otherwise-                         -> Q Type-buildTypeInstanceFromTys gClass tyConName varTysOrig isDataFamily = do+                         -> Q (Type, Kind)+buildTypeInstanceFromTys gClass useKindSigs tyConName varTysOrig = do     -- Make sure to expand through type/kind synonyms! Otherwise, the     -- eta-reduction check might get tripped up over type variables in a     -- synonym that are actually dropped.@@ -920,35 +1054,30 @@     when (remainingLength < 0 || any (== NotKindStar) droppedStarKindStati) $       derivingKindError tyConName -    let droppedKindVarNames :: [Name]-        droppedKindVarNames = catKindVarNames droppedStarKindStati-         -- Substitute kind * for any dropped kind variables-        varTysExpSubst :: [Type]+    let varTysExpSubst :: [Type]+-- See Note [Generic1 is polykinded on GHC 8.2]+#if __GLASGOW_HASKELL__ >= 801+        varTysExpSubst = varTysExp+#else         varTysExpSubst = map (substNamesWithKindStar droppedKindVarNames) varTysExp -    -- We must take care to avoid allowing Generic1 instances where a visible kind-    -- binder is instantiated to * (which should only happen in the presence of-    -- -XTypeInType). See the documentation for instantiationError for an example-    -- of when this can occur.-    ---    -- A quick-and-dirty way to accomplish this is to check if the visible type-    -- binders of the original type, and of the type post-synonym-expansion, are-    -- both the same. If not, it's likely that one of the type binders was-    -- instantiated to a specific type (likely *).-    when (concatMap visibleTyVarsOfType varTysExp-            /= concatMap visibleTyVarsOfType varTysExpSubst) $-      instantiationError tyConName+        droppedKindVarNames :: [Name]+        droppedKindVarNames = catKindVarNames droppedStarKindStati+#endif      let remainingTysExpSubst, droppedTysExpSubst :: [Type]         (remainingTysExpSubst, droppedTysExpSubst) =           splitAt remainingLength varTysExpSubst +-- See Note [Generic1 is polykinded on GHC 8.2]+#if __GLASGOW_HASKELL__ < 801     -- If any of the dropped types were polykinded, ensure that there are of     -- kind * after substituting * for the dropped kind variables. If not,     -- throw an error.     unless (all hasKindStar droppedTysExpSubst) $       derivingKindError tyConName+#endif          -- We now substitute all of the specialized-to-* kind variable names         -- with *, but in the original types, not the synonym-expanded types. The reason@@ -966,32 +1095,45 @@         -- Not:         --         --   instance C (Fam [Char])-    let remainingTysOrigSubst :: [Type]-        remainingTysOrigSubst =+    let varTysOrigSubst :: [Type]+        varTysOrigSubst =+-- See Note [Generic1 is polykinded on GHC 8.2]+#if __GLASGOW_HASKELL__ >= 801+          id+#else           map (substNamesWithKindStar droppedKindVarNames)-            $ take remainingLength varTysOrig+#endif+            $ varTysOrig +        remainingTysOrigSubst, droppedTysOrigSubst :: [Type]+        (remainingTysOrigSubst, droppedTysOrigSubst) =+            splitAt remainingLength varTysOrigSubst+         remainingTysOrigSubst' :: [Type]         -- See Note [Kind signatures in derived instances] for an explanation-        -- of the isDataFamily check.+        -- of the useKindSigs check.         remainingTysOrigSubst' =-          if isDataFamily+          if useKindSigs              then remainingTysOrigSubst              else map unSigT remainingTysOrigSubst          instanceType :: Type         instanceType = applyTyToTys (ConT tyConName) remainingTysOrigSubst' +        -- See Note [Kind signatures in derived instances]+        instanceKind :: Kind+        instanceKind = makeFunKind (map typeKind droppedTysOrigSubst) starK+     -- Ensure the dropped types can be safely eta-reduced. Otherwise,     -- throw an error.     unless (canEtaReduce remainingTysExpSubst droppedTysExpSubst) $       etaReductionError instanceType-    return instanceType+    return (instanceType, instanceKind)  -- See Note [Arguments to generated type synonyms]-grabTyVarBndrsFromCons :: GenericClass -> [Con] -> Q [TyVarBndr]-grabTyVarBndrsFromCons _      []      = return []-grabTyVarBndrsFromCons gClass (con:_) =+grabTyVarsFromCons :: GenericClass -> [Con] -> Q [Type]+grabTyVarsFromCons _      []      = return []+grabTyVarsFromCons gClass (con:_) =     fmap fst3 $ reifyConTys gClass (constructorName con)  {-@@ -1030,12 +1172,13 @@ corresponding type variables from the data declaration.  There is another obscure case where we need to do a type subtitution. With--XTypeInType enabled, you might have something like this:+-XTypeInType enabled on GHC 8.0, you might have something like this:    data Proxy (a :: k) (b :: k) = Proxy k deriving Generic1  Then k gets specialized to *, which means that k should NOT show up in the RHS of a Rep1 type instance! To avoid this, make sure to substitute k with *.+See also Note [Generic1 is polykinded on GHC 8.2].  Note [Arguments to generated type synonyms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -1108,33 +1251,77 @@ Note [Kind signatures in derived instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is possible to put explicit kind signatures into the derived instances, e.g.,+We generally include explicit type signatures in derived instances. One reason for+doing so is that in the case of certain data family instances, not including kind+signatures can result in ambiguity. For example, consider the following two data+family instances that are distinguished by their kinds: -  instance C a => C (Data (f :: * -> *)) where ...+  data family Fam (a :: k)+  data instance Fam (a :: * -> *)+  data instance Fam (a :: *) -But it is preferable to avoid this if possible. If we come up with an incorrect-kind signature (which is entirely possible, since our type inferencer is pretty-unsophisticated - see Note [Type inference in derived instances]), then GHC will-flat-out reject the instance, which is quite unfortunate.+If we dropped the kind signature for a in a derived instance for Fam a, then GHC+would have no way of knowing which instance we are talking about. -Plain old datatypes have the advantage that you can avoid using any kind signatures-at all in their instances. This is because a datatype declaration uses all type-variables, so the types that we use in a derived instance uniquely determine their-kinds. As long as we plug in the right types, the kind inferencer can do the rest-of the work. For this reason, we use unSigT to remove all kind signatures before-splicing in the instance context and head.+Another motivation for explicit kind signatures is the -XTypeInType extension.+With -XTypeInType, dropping kind signatures can completely change the meaning+of some data types. For example, there is a substantial difference between these+two data types: -Data family instances are trickier, since a data family can have two instances that-are distinguished by kind alone, e.g.,+  data T k (a :: k) = T k+  data T k a        = T k -  data family Fam (a :: k)-  data instance Fam (a :: * -> *)-  data instance Fam (a :: *)+In addition to using explicit kind signatures on type variables, we also put+explicit return kinds in the instance head, so generated instances will look+something like this: -If we dropped the kind signatures for C (Fam a), then GHC will have no way of-knowing which instance we are talking about. To avoid this scenario, we always-include explicit kind signatures in data family instances. There is a chance that-the inferred kind signatures will be incorrect, but if so, we can always fall back-on the make- functions.+  data S (a :: k) = S k+  instance Generic1 (S :: k -> *) where+    type Rep1 (S :: k -> *) = ... (Rec0 k) +Why do we do this? Imagine what the instance would be without the explicit return kind:++  instance Generic1 S where+    type Rep1 S = ... (Rec0 k)++This is an error, since the variable k is now out-of-scope!++Although explicit kind signatures are the right thing to do in most cases, there+are sadly some degenerate cases where this isn't true. Consider this example:++  newtype Compose (f :: k2 -> *) (g :: k1 -> k2) (a :: k1) = Compose (f (g a))++The Rep1 type instance in a Generic1 instance for Compose would involve the type+(f :.: Rec1 g), which forces (f :: * -> *). But this library doesn't have very+sophisticated kind inference machinery (other than what is mentioned in+Note [Substituting types in constructor type signatures]), so at the moment we+have no way of actually unifying k1 with *. So the naïve generated Generic1+instance would be:++  instance Generic1 (Compose (f :: k2 -> *) (g :: k1 -> k2)) where+    type Rep1 (Compose f g) = ... (f :.: Rec1 g)++This is wrong, since f's kind is overly generalized. To get around this issue,+there are variants of the TH functions that allow you to configure the KindSigOptions.+If KindSigOptions is set to False, then generated instances will not include+explicit kind signatures, leaving it up to GHC's kind inference machinery to+figure out the correct kinds.++Note [Generic1 is polykinded on GHC 8.2]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Prior to GHC 8.2, Generic1 :: (* -> *) -> Constraint. This means that if a Generic1+instance is defined for a polykinded data type like so:++  data Proxy k (a :: k) = Proxy++Then k is unified with *, and this has an effect on the generated Generic1 instance:++  instance Generic1 (Proxy *) where ...++We must take great care to ensure that all occurrences of k are substituted with *,+or else the generated instance will be ill kinded.++On GHC 8.2 and later, Generic1 :: (k -> *) -> Constraint. This means we don't have+to do this kind unification anymore! Hooray! -}
src/Generics/Deriving/TH/Internal.hs view
@@ -105,16 +105,17 @@ substNamesWithKindStar :: [Name] -> Type -> Type substNamesWithKindStar ns t = foldr' (flip substNameWithKind starK) t ns -substTyVarBndrKind :: KindSubst -> TyVarBndr -> TyVarBndr-substTyVarBndrKind _subs (KindedTV n k) = KindedTV n $+substTyVarBndrType :: TypeSubst -> TyVarBndr -> Type+substTyVarBndrType subs = substType subs . tyVarBndrToType++substTyVarBndrKind :: KindSubst -> TyVarBndr -> Type #if MIN_VERSION_template_haskell(2,8,0)-    substKind _subs k+substTyVarBndrKind = substTyVarBndrType #else-    k+substTyVarBndrKind _ = tyVarBndrToType #endif-substTyVarBndrKind _ tvb = tvb -substNameWithKindStarInTyVarBndr :: Name -> TyVarBndr -> TyVarBndr+substNameWithKindStarInTyVarBndr :: Name -> TyVarBndr -> Type substNameWithKindStarInTyVarBndr n = substTyVarBndrKind (Map.singleton n starK)  -------------------------------------------------------------------------------@@ -162,10 +163,6 @@ #endif hasKindStar _              = False -tyVarNamesOfTyVarBndr :: TyVarBndr -> [Name]-tyVarNamesOfTyVarBndr (PlainTV n)    = [n]-tyVarNamesOfTyVarBndr (KindedTV n k) = n:kindVarNamesOfKind k- -- | Gets all of the type/kind variable names mentioned somewhere in a Type. tyVarNamesOfType :: Type -> [Name] tyVarNamesOfType = go@@ -179,19 +176,24 @@     go (VarT n)     = [n]     go _            = [] --- | Gets all of the kind variable names mentioned somewhere in a Kind.-kindVarNamesOfKind :: Kind -> [Name]+-- | Gets all of the type/kind variable binders mentioned in a Type.+tyVarsOfType :: Type -> [TyVarBndr]+tyVarsOfType = go+  where+    go :: Type -> [TyVarBndr]+    go (AppT t1 t2) = go t1 ++ go t2+    go (SigT t _k)  = go t #if MIN_VERSION_template_haskell(2,8,0)-kindVarNamesOfKind = tyVarNamesOfType-#else-kindVarNamesOfKind _ = [] -- There are no kind variables+                           ++ go _k #endif+    go (VarT n)     = [PlainTV n]+    go _            = [] --- | Gets all of the specified type/kind variable names mentioned in a Type. In--- contrast to 'tyVarNamesOfType', 'visibleTyVarsOfType' does not go into kinds+-- | Gets all of the required type/kind variable binders mentioned in a Type. In+-- contrast to 'tyVarsOfType', 'requiredTyVarsOfType' does not go into kinds -- of 'SigT's.-visibleTyVarsOfType :: Type -> [TyVarBndr]-visibleTyVarsOfType = go+requiredTyVarsOfType :: Type -> [TyVarBndr]+requiredTyVarsOfType = go   where     go :: Type -> [TyVarBndr]     go (AppT t1 t2) = go t1 ++ go t2@@ -199,6 +201,50 @@     go (VarT n)     = [PlainTV n]     go _            = [] +-- | Converts a VarT or a SigT into Just the corresponding TyVarBndr.+-- Converts other Types to Nothing.+typeToTyVarBndr :: Type -> Maybe TyVarBndr+typeToTyVarBndr (VarT n)          = Just (PlainTV n)+typeToTyVarBndr (SigT (VarT n) k) = Just (KindedTV n k)+typeToTyVarBndr _                 = Nothing++-- | If a Type is a SigT, returns its kind signature. Otherwise, return *.+typeKind :: Type -> Kind+typeKind (SigT _ k) = k+typeKind _          = starK++-- | Turns+--+-- @+-- [a, b] c+-- @+--+-- into+--+-- @+-- a -> b -> c+-- @+makeFunType :: [Type] -> Type -> Type+makeFunType argTys resTy = foldr' (AppT . AppT ArrowT) resTy argTys++-- | Turns+--+-- @+-- [k1, k2] k3+-- @+--+-- into+--+-- @+-- k1 -> k2 -> k3+-- @+makeFunKind :: [Kind] -> Kind -> Kind+#if MIN_VERSION_template_haskell(2,8,0)+makeFunKind = makeFunType+#else+makeFunKind argKinds resKind = foldr' ArrowK resKind argKinds+#endif+ -- | Is the given type a type family constructor (and not a data family constructor)? isTyFamily :: Type -> Q Bool isTyFamily (ConT n) = do@@ -357,14 +403,6 @@     go VarT{}       = False     go _            = True --- | Returns 'True' is a 'Kind' contains no kind variables.-isKindMonomorphic :: Kind -> Bool-#if MIN_VERSION_template_haskell(2,8,0)-isKindMonomorphic = isTypeMonomorphic-#else-isKindMonomorphic _ = True -- There are no kind variables-#endif- -- | Peel off a kind signature from a Type (if it has one). unSigT :: Type -> Type unSigT (SigT t _) = t@@ -456,11 +494,12 @@ data GenericKind = Gen0                  | Gen1 Name (Maybe Name) --- Determines the universally quantified type variables, the types of a constructor's+-- Determines the universally quantified type variables (possibly after+-- substituting * in the case of Generic1), the types of a constructor's -- arguments, and the last type parameter name (if there is one). reifyConTys :: GenericClass             -> Name-            -> Q ([TyVarBndr], [Type], GenericKind)+            -> Q ([Type], [Type], GenericKind) reifyConTys gClass conName = do     info <- reify conName     let (tvbs, uncTy) = case info of@@ -479,43 +518,48 @@     --     -- which you'd only be able to tell was legal if you expand Constant a b to a!     resTyExp <- expandSyn resTy-    let numResTyVars = length . nub $ visibleTyVarsOfType resTyExp-        -- ^ We need to grab a number of type variables from the constructor's+    let numResTyVars = length . nub $ requiredTyVarsOfType resTyExp+        -- We need to grab a number of types from the constructor's         -- type signature to re-use for the Rep(1) type synonym's type variable         -- binders. As it turns out, that number is equal to the number of distinct         -- type variables which appear in the result type.         ---        -- We assume that the visible type variables all come last in the list+        -- We assume that the required types all come last in the list         -- of forall'd type variables. I suppose nothing guarantees this, but         -- this seems to always be the case via experimentation. Fingers crossed.-        -- TODO: This doesn't work with -XTypeInType and data families-        visibleTvbs = drop (length tvbs - numResTyVars) tvbs-    let (visibleTvbs', gk) = case gClass of-           Generic  -> (visibleTvbs, Gen0)+        requiredTvbs = drop (length tvbs - numResTyVars) tvbs+    let (requiredTyVars', gk) = case gClass of+           Generic  -> (map tyVarBndrToType requiredTvbs, Gen0)            Generic1 ->              -- If deriving Generic1 and the last type variable is polykinded,              -- make sure to substitute that kind with * in the other type              -- variable binders' kind signatures-             let headVisibleTvbs :: [TyVarBndr]-                 lastVisibleTvb :: TyVarBndr-                 (headVisibleTvbs, [lastVisibleTvb]) =-                   splitAt (length visibleTvbs - 1) visibleTvbs+             let headRequiredTvbs :: [TyVarBndr]+                 lastRequiredTvb :: TyVarBndr+                 (headRequiredTvbs, [lastRequiredTvb]) =+                   splitAt (length requiredTvbs - 1) requiredTvbs                   mbLastArgKindName :: Maybe Name                  mbLastArgKindName = starKindStatusToName                                    . canRealizeKindStar-                                   $ tyVarBndrToType lastVisibleTvb+                                   $ tyVarBndrToType lastRequiredTvb -                 visibleTvbsSubst :: [TyVarBndr]-                 visibleTvbsSubst =+                 requiredTyVars :: [Type]+                 requiredTyVars =                    case mbLastArgKindName of-                        Nothing   -> headVisibleTvbs-                        Just lakn -> map (substNameWithKindStarInTyVarBndr lakn)-                                         headVisibleTvbs-             in ( visibleTvbsSubst-                , Gen1 (tyVarBndrName lastVisibleTvb) mbLastArgKindName+                        Nothing   -> map tyVarBndrToType headRequiredTvbs+                        Just _lakn ->+-- See Note [Generic1 is polykinded on GHC 8.2] in Generics.Deriving.TH+#if __GLASGOW_HASKELL__ >= 801+                          map tyVarBndrToType headRequiredTvbs+#else+                          map (substNameWithKindStarInTyVarBndr _lakn)+                              headRequiredTvbs+#endif+             in ( requiredTyVars+                , Gen1 (tyVarBndrName lastRequiredTvb) mbLastArgKindName                 )-    return (visibleTvbs', argTys, gk)+    return (requiredTyVars', argTys, gk)  -- | Indicates whether Generic(1) is being derived for a plain data type (DataPlain) -- or a data family instance (DataFamily). DataFamily bundles the Name of the data@@ -576,21 +620,6 @@ -- when deriving Generic(1) rankNError :: a rankNError = error "Cannot have polymorphic arguments"---- | Cannot have a Generic(1) instance where the instance head's type is instantiated--- to be a more "saturated" type than the original data declaration. That means--- something like this would be rejected:------ @--- {-# LANGUAGE TypeInType #-}--- data Hm k (a :: k) deriving Generic1--- @------ Since having a Generic1 instance would force k to be instantiated with *,--- resulting in an instance Generic1 (Hm *) instead of instance Generic1 (Hm k).-instantiationError :: Name -> a-instantiationError tyConName = error $-    nameBase tyConName ++ " must not be instantiated"  -- | Boilerplate for top level splices. --