[GHC] #10598: DeriveAnyClass and GND don't work well together
GHC
ghc-devs at haskell.org
Wed Aug 3 23:36:18 UTC 2016
#10598: DeriveAnyClass and GND don't work well together
-------------------------------------+-------------------------------------
Reporter: osa1 | Owner: RyanGlScott
Type: bug | Status: patch
Priority: normal | Milestone: 8.2.1
Component: Compiler | Version: 7.11
Resolution: | Keywords: Generics
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D2280
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by RyanGlScott):
Replying to [comment:40 oerjan]:
> Is it still the case that using any other deriving strategy than
`bespoke` for a class that supports `bespoke` requires using this new
extension?
The short answer is: yes. The longer, more nuanced answer is that GHC
sometimes picks to derive certain "standard" classes using GND when they
would produce the same instance (see "The deriving strategy resolution
algorithm" section of
[https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/DerivingStrategies
this wiki page] for more info). For example, `newtype Foo = Foo Int
deriving Eq` actually uses GND to derive the `Eq` instance, not the
bespoke instance you'd normally get for `Eq`. Most of the time, though, if
you derive a standard class without a keyword, it'll default to the
`bespoke` strategy.
> If not, then that could lead to confusing errors, like accidentally
deriving `Functor` with anyclass because `DeriveAnyClass` is enabled but
`DeriveFunctor` has been forgotten, and would probably warrant some more
warnings.
This is a valid concern, but luckily that doesn't happen, even with the
current GHC. Currently, GHC's outlook is that `DeriveAnyClass` should
//never// kick in for standard classes. As a result, if you try compiling
this program:
{{{#!hs
{-# LANGUAGE DeriveAnyClass #-}
newtype T a = T (Maybe a) deriving Functor
}}}
it will error with:
{{{
Can't make a derived instance of ‘Functor T’:
You need DeriveFunctor to derive an instance for this class
Try GeneralizedNewtypeDeriving for GHC's newtype-deriving extension
In the newtype declaration for ‘T’
}}}
whereas for nonstandard classes, `DeriveAnyClass` kicks in. Since none of
the standard classes use `DefaultSignatures`, I think this special case is
probably acceptable (and if you //really// want to derive your `Functor`
instance using `DeriveAnyClass` for some bizarre reason, you'll be able to
with `DerivingStrategies`).
> On the other hand, I think GND would give equivalent result to `bespoke`
for many classes, so it might be convenient ''not'' to warn in those
cases. E.g. when someone wants to derive `Functor`, `Applicative` and
`Monad` for their monad stack newtype, it seems almost reasonable that
only GND needs to be enabled, and not `DeriveFunctor`.
It is indeed reasonable, and GHC does sometimes choose to pick
`GeneralizedNewtypeDeriving` over the `DeriveFunctor` algorithm when the
last type variable can be eta-reduced (again, see
[https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/DerivingStrategies
this wiki page] for the full story). Emphatically, Phab:D2280 will not
change any of this existing behavior. The only things it does are (1) fix
the bug reported in the original comment and (2) give you the ability to
choose explicitly which strategy to use, and hence bypass the confusing
algorithm GHC uses to choose a strategy implicitly in the absence of a
strategy keyword.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10598#comment:41>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list