[GHC] #16300: Make TH always reify data types with explicit return kinds

GHC ghc-devs at haskell.org
Sun Feb 10 15:27:29 UTC 2019


#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


More information about the ghc-tickets mailing list