[GHC] #13065: Prohibit user-defined Generic and Generic1 instances

GHC ghc-devs at haskell.org
Wed Jan 4 18:50:45 UTC 2017


#13065: Prohibit user-defined Generic and Generic1 instances
-------------------------------------+-------------------------------------
        Reporter:  dfeuer            |                Owner:
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:  8.4.1
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:  Generics
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  Other             |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by RyanGlScott):

 I'm not as experienced with `Data.Data` as I am with `GHC.Generics`, so
 take my comments with a grain of salt. But the impression that I've
 gathered after working with it a little bit is that `Data.Data` has
 slightly different goals than `GHC.Generics`.

 With the former (`Data`), you mostly care about generically walking over
 data structures. That seems to explain why `Data.Data` gives you only a
 bare-minimum amount of metadata for each datatype and constructor, as
 they're only useful insofar as they serve as signposts when you're deep in
 a datatype traversal. Moreover, the documentation in `Data.Data` mentions
 the phrase "public representation" in several places. It seems acceptable
 to lie a little in certain `Data` instances—e.g., in primitive datatypes
 like `Int`, or abstract types like `Map`—in order to give programmers
 //some// interface that they can walk over.

 With the latter (`Generic`), there's an expectation that the
 representation type provides a faithful view of the datatype's structure
 and metadata. It occurs to me that we really don't state this expectation
 anywhere in the documentation, but this is nonetheless the reasoning that
 David Terei alluded to when he made the change to disallow hand-written
 `Generic` instances in 578fbeca31dd3d755e24e910c3a7327f92bc4ee3. If we
 allow users to hand-write their `Generic` instances, then I feel that we
 are allowing them to shoot themselves in the foot.

 Of course, the other thing that `Data` and `Generic` have in common is
 that they facilitate the ability to reduce boilerplate code. But even if
 you can't write `Generic` instances for your abstract types, you can still
 use `GHC.Generics` to help reduce boilerplate: just use the `Generic`
 instance for an isomorphic type. For instance, if you want to think of
 `Data.Map` as a list of key-value pairs, then you have the power to do so:


 {{{#!hs
 module Main (main) where

 import Data.Map
 import Generics.Deriving.Eq
 import GHC.Generics

 eqMapKVList :: (GEq k, GEq v) => Map k v -> Map k v -> Bool
 eqMapKVList x y = geq (toListRep x) (toListRep y)
   where
     toListRep :: Map k v -> Rep [(k, v)] ()
     toListRep = from . toList

 main :: IO ()
 main = do
     print $ eqMapKVList (fromList [('a', 'b')]) (fromList [('a', 'b')])
     print $ eqMapKVList (fromList [('a', 'b')]) (fromList [('a', 'c')])
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13065#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list