
#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