#5499: Tagging constructors with record/product phantom type
---------------------------------+------------------------------------------
    Reporter:  basvandijk        |       Owner:                   
        Type:  feature request   |      Status:  new              
    Priority:  normal            |   Component:  libraries (other)
     Version:  7.2.1             |    Keywords:                   
    Testcase:                    |   Blockedby:                   
          Os:  Unknown/Multiple  |    Blocking:                   
Architecture:  Unknown/Multiple  |     Failure:  None/Unknown     
---------------------------------+------------------------------------------
 As mentioned in [http://www.haskell.org/pipermail/glasgow-haskell-
 users/2011-September/020953.html this discussion] on the `glasgow-haskell-
 users` mailinglist. I would like to propose making the following changes
 to [http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.2.0.0
 /GHC-Generics.html GHC.Generics]:

 == Proposal ==

  * Add a phantom type to the
 [http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.2.0.0
 /GHC-Generics.html#t:C C] type which specifies whether it's a record or a
 normal product using the empty datatypes:

 {{{
 data Record
 data Product
 }}}

  * Optionally add the type synonyms:

 {{{
 type R1 = M1 (C Record)
 type P1 = M1 (C Product)
 }}}

  * Optionally remove the `conIsRecord` method of the `Constructor` type
 class.


 Of course GHC has to be modified too, so that the generated `C`s are
 properly tagged.

 == Motiviation ==

 Having the information, whether a constructor is a record or not,
 statically available instead of only dynamically, has the following
 advantages:

  * More efficient: programs can make a static instead of a dynamic choice.
 (To be fair, the case branches on `conIsRecord` should in most cases be
 optimized away)

  * No unnecessary constraints for constructor instances:

 See
 
[https://github.com/basvandijk/aeson/blob/5bdf30ed4b32f2cc169f6e4e58d1688bcb02c197/Data/Aeson/Types/Internal.hs#L925
 the code] that triggered this proposal:

 {{{
 instance (Constructor c, GRecordToObject a, GToJSON a) => GToJSON (C1 c a)
 where
     gToJSON m1@(M1 x)
         | conIsRecord m1 = Object $ gRecordToObject x
         | otherwise = gToJSON x
 }}}

 Note the `GRecordToObject` constraint. This constraint is only really
 necessary in case of a record. Down the line this extra constraint
 requires
 
[https://github.com/basvandijk/aeson/blob/5bdf30ed4b32f2cc169f6e4e58d1688bcb02c197/Data/Aeson/Types/Internal.hs#L988
 the following] ugly undefined instances:

 {{{
 instance GRecordToObject (a :+: b)  where gRecordToObject = undefined
 instance GRecordToObject U1         where gRecordToObject = undefined
 instance GRecordToObject (K1 i c)   where gRecordToObject = undefined
 instance GRecordToObject (M1 i c f) where gRecordToObject = undefined
 }}}

 == Process ==

 Since `GHC.Generics` is part of the `ghc-prim` package I don't think this
 proposal has to go through the whole library submission process. But if it
 must I will have no problem supervising it.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5499>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to