[GHC] #10598: DeriveAnyClass and GND don't work well together

GHC ghc-devs at haskell.org
Tue Jul 14 06:27:03 UTC 2015


#10598: DeriveAnyClass and GND don't work well together
-------------------------------------+-------------------------------------
        Reporter:  osa1              |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.11
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
 Type of failure:  None/Unknown      |  Unknown/Multiple
      Blocked By:                    |               Test Case:
 Related Tickets:                    |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by kosmikus):

 Ok, here's my take on this.

 The behaviour is clearly inconsistent.

 Let's compare ghc-7.8.4 and ghc-7.10.1. There are three flags that play a
 role here, namely `GeneralizedNewtypeDeriving` (GND), `DeriveFunctor`
 (DF), and `DeriveAnyClass` (DAC). The DAC flag ist not supported by
 ghc-7.8.4. We have the following results:

 ||                || ghc-7.8.4   || ghc-7.10.1   ||
 || no flags       || error (GND) || error (GND)  ||
 || GND            || ok (GND)    || ok (GND)     ||
 || DF             || ok (DF)     || ok (DF)      ||
 || GND + DF       || ok (GND)    || ok (GND)     ||
 || DAC            || unsupported || error (GND)  ||
 || DAC + GND      || unsupported || error (GND') ||
 || DAC + DF       || unsupported || ok (DF)      ||
 || DAC + GND + DF || unsupported || warning (??) ||

 So the good news is that without the use of DAC, both GHC versions behave
 the same. However, in the presence of DAC, several things go wrong.

 In the DAC case, an error is reported suggesting the use of GND instead.
 That's strange, because doing the same thing for a user-defined
 `MyFunctor` class will actually happily work. I know we've had a long
 discussion about the conditions for using DAC in the past. In principle,
 I'd like it if it wouldn't work on "any" class, but instead would require
 the presence of defaults. It doesn't make much sense to derive partial
 class definitions with missing methods. I'm not entirely sure what the
 reason may have been to lift this restriction.

 The DAC + GND case is probably the worst. We get a completely unhelpful
 error message, saying that GND doesn't work yet suggesting to enable GND.
 Also, it's a case where the mere presence of DAC makes things break all of
 a sudden, because removing DAC will happily make GHC use GND and succeed.

 In the DAC + DF, we silently prefer the built-in functor deriving, which
 at least in this case seems useful, because DAC for the built-in functor
 would yield a partial class definition.

 The DAC + GND + DF case yields a warning that indicates that both DAC and
 GND are available to derive the `Functor` instance, and that it is
 defaulting to DAC! Yet it
 then seems to use DF to derive the actual `Functor` instance. So again,
 the outcome isn't too bad, but the warning is clearly misleading.

 What to do about all this? I think there are the following issues:

    * Should `DAC` work only if defaults are present for all methods, or
 should it work also in other situations? I cannot think of a good reason
 not to require defaults for all methods right now?

    * I think that if, given by the flags and imposed restrictions, only
 one of the three deriving methods is available, that one should clearly be
 taken.

    * If several deriving methods are available, we might still choose one.
 I think the natural thing is to choose built-in deriving before GND before
 DAC. In all such cases, it should probably produce a warning.

    * I very much like Richard's idea to allow PRAGMAs to explicitly
 indicate the desired deriving method in a deriving clause. This would be
 both a way to change default behaviour used by GHC and to remove warnings,
 because you'd explicitly document intent.

    * If no deriving method is available but a deriving clause is used, we
 should suggest both GND or DAC as options, but only if they're actually
 available.

 It's entirely possible that I've overlooked important cases. Suggestions
 welcome.

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


More information about the ghc-tickets mailing list