
#16300: Make TH always reify data types with explicit return kinds -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: Template | Version: 8.6.3 Haskell | Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Currently, whenever you reify a data type with Template Haskell, it will return a `DataD`/`NewtypeD` where the return kind information has been set to `Nothing`: {{{ λ> 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 [https://phabricator.haskell.org/D4777 unlifted newtypes], however, things become murkier. `UnliftedNewtypes` let you define newtypes like this one: {{{#!hs 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)) []) }}} Still `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? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/16300 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler