[GHC] #13368: Derive superclasses automatically if possible

GHC ghc-devs at haskell.org
Fri Mar 3 14:24:04 UTC 2017


#13368: Derive superclasses automatically if possible
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                Owner:  (none)
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #10607            |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by RyanGlScott):

 This proposal shares many similarities with the
 [https://ghc.haskell.org/trac/ghc/wiki/IntrinsicSuperclasses
 IntrinsicSuperclasses] and
 [https://ghc.haskell.org/trac/ghc/wiki/InstanceTemplates
 InstanceTemplates] proposals, so I'll link them here. However, this
 proposal shares many of their downsides, which I'll briefly expound upon
 here.

 First, there's the technical challenges to this proposal. Not all
 instances are made equal, and `deriving` exposes this in many ways. For
 instance, suppose you tried this under your proposal:

 {{{#!hs
 class Traversable f => Witherable f where ...

 newtype Wrapped f a = Wrap (f a)
   deriving newtype Witherable
 }}}

 This would attempt the following:

 * `deriving newtype instance Functor f => Functor (Wrapped f)`
 * `deriving newtype instance Foldable f => Foldable (Wrapped f)`
 * `deriving newtype instance Traversable f => Traversable (Wrapped f)`
 * `deriving newtype instance Witherable f => Witherable (Wrapped f)`

 But trying to derive `Traversable` that way will fail, as it is ill-roled!
 See #13153. So not only would this throw an error, but it would throw an
 error that talks about a completely different class than `Witherable`.
 Mysterious.

 What's more, there's quite a number of ambiguities you'd have to deal
 with. For instance, what happens under your proposal in this scenario?

 {{{#!hs
 class Show a => MyShow a where ...

 data Foo
   deriving newtype MyShow

 instance Show Foo
 }}}

 Since `Show` is a superclass of `MyShow`, you might expect the `deriving
 newtype MyShow` clause to derive `instance Show Foo` as well. But there's
 already an `instance Show Foo`! So we'd either have to error here, or come
 up with a scheme for defaulting to existing instances when scenarios like
 the above one crop up.

 You might respond: "But that's easy! Just use the existing `Show Foo`
 instance!" But it gets even hairier than that:

 {{{#!hs
 class Show a => MyShow1 a where ...
 class Show a => MyShow2 a where ...

 data Foo
   deriving newtype MyShow1
   deriving anyclass MyShow2
 }}}

 Now we must ask: which of the two deriving clauses will implicitly derive
 `Show` behind the scenes? The choice matters, because a `newtype`-derived
 `Show` instance will be completely different than an `anyclass`-derived
 one! If the answer to this question is "use the first deriving clause",
 then now the order in which you write `deriving` clauses matters, which is
 a property that Haskell has never had up to this point.

 Finally, there's one more objection I will make not on technical grounds,
 but on aesthetic ones. This proposal would lose the property that all
 instances are explicitly asked for by the user. I (personally) find the
 idea of instances being snuck in behind the scenes quite shady and hard to
 reason about, and in addition, we'd lose things like concrete source
 locations for every instance, the ability to annotate all instances with
 Haddocks, etc.

 So my opinion in that it's a huge amount of complexity for very little
 gain and many drawbacks. I like the idea of doing something like this in
 Template Haskell, so I'm glad that someone is pursuing this in #10607.

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


More information about the ghc-tickets mailing list