Make TH always reify data types with explicit return kinds
Currently, whenever you reify a data type with Template Haskell, it will return a
NewtypeD where the return kind information has been set to
λ> putStrLn $(reify ''Bool >>= stringE . show) TyConI (DataD  GHC.Types.Bool  Nothing [NormalC GHC.Types.False ,NormalC GHC.Types.True ] )
One could argue that this isn't a problem since data types always have return kind
Type anyway. For 99% of data types, this is true. There are a handful of exceptions, such as unboxed tuples (with return kind
TYPE (TupleRep [...]), but those could be dismissed as unusual special cases.
With the advent of unlifted newtypes, however, things become murkier.
UnliftedNewtypes let you define newtypes like this one:
newtype Foo :: TYPE IntRep where MkFoo :: Int# -> Foo
Notice how the return kind is //not//
Type, but instead
TYPE IntRep. However, TH reification doesn't clue you in to this fact:
λ> putStrLn $(reify ''Foo >>= stringE . show) TyConI (NewtypeD  Ghci8.Foo  Nothing (GadtC [Ghci8.MkFoo] [(Bang NoSourceUnpackedness NoSourceStrictness,ConT GHC.Prim.Int#)] (ConT Ghci8.Foo)) )
Nothing. There's no easy way in general to determine what the return kind of an unlifted newtype is using TH reification, which is unfortunate.
Luckily, I think there's a very simple fix that we could apply here: just have TH reification return
Just (<kind>) instead of
Nothing! There's no technical reason why TH couldn't do this; the only reason it currently returns
Nothing is due to historical convention. Moreover, I doubt that this would even break any code in the wild, since
Nothing doesn't convey any useful information in the context of TH reification anyway.
Does this sound reasonable?