GHC issueshttps://gitlab.haskell.org/ghc/ghc//issues20210608T20:26:59Zhttps://gitlab.haskell.org/ghc/ghc//issues/19849Compiler panic with unused existential type variable and O220210608T20:26:59ZXia LiyaoCompiler panic with unused existential type variable and O2## Summary
The following file makes GHC panic:
```haskell
 B.hs
{# LANGUAGE
DeriveDataTypeable,
StandaloneDeriving,
GADTs,
ScopedTypeVariables #}
module B where
import Data.Data (Data(..))
data T where
C :: forall k. T
deriving instance Data T
```
## Steps to reproduce
```
ghc O B.hs
```
Output:
```
[1 of 1] Compiling B ( test/B.hs, test/B.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.10.4:
setBndrsDemandInfo
[k_a15F]
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1179:37 in ghc:Outputable
pprPanic, called at compiler/stranal/DmdAnal.hs:964:28 in ghc:DmdAnal
```
## Expected behavior
Should compile successfully.
## Environment
* GHC version used: 8.10, 9.0.1## Summary
The following file makes GHC panic:
```haskell
 B.hs
{# LANGUAGE
DeriveDataTypeable,
StandaloneDeriving,
GADTs,
ScopedTypeVariables #}
module B where
import Data.Data (Data(..))
data T where
C :: forall k. T
deriving instance Data T
```
## Steps to reproduce
```
ghc O B.hs
```
Output:
```
[1 of 1] Compiling B ( test/B.hs, test/B.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.10.4:
setBndrsDemandInfo
[k_a15F]
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1179:37 in ghc:Outputable
pprPanic, called at compiler/stranal/DmdAnal.hs:964:28 in ghc:DmdAnal
```
## Expected behavior
Should compile successfully.
## Environment
* GHC version used: 8.10, 9.0.1https://gitlab.haskell.org/ghc/ghc//issues/19936Odd GND failure/success20210608T14:22:57ZDavid FeuerOdd GND failure/successThere's currently a discussion about whether to change the definition of `MonadTrans` to use `QuantifiedConstraints`:
```haskell
class (forall m. Monad m => Monad (t m)) => MonadTrans t where
lift :: m a > t m a
```
I wondered if this works with GND. As it turns out, the answer is yes:
```haskell
newtype B t (m :: Type > Type) a => B (t m a)
deriving (Functor, Applicative, Monad)
 StandaloneDeriving just to be sure the constraints is
 what I expect.
deriving instance MonadTrans t => MonadTrans (B t)
```
compiles just fine. But a conceptually very similar idea does not:
```haskell
class MonadTrans t where
lift :: m a > t m a
liftMonad :: Monad m => Proxy (t m) > (Monad (t m) => r) > r
```
This one produces an error,
```
Lift.hs:9:42: error:
• Occurs check: cannot construct the infinite type: t ~ B t
arising from the coercion of the method ‘liftMonad’
from type ‘forall (m :: * > *) r.
Monad m =>
Proxy (t m) > (Monad (t m) => r) > r’
to type ‘forall (m :: * > *) r.
Monad m =>
Proxy (B t m) > (Monad (B t m) => r) > r’
• When deriving the instance for (MonadTrans (B t))
```
Why does one work and not the other? Is there a good reason for that, or should they both succeed or both fail?There's currently a discussion about whether to change the definition of `MonadTrans` to use `QuantifiedConstraints`:
```haskell
class (forall m. Monad m => Monad (t m)) => MonadTrans t where
lift :: m a > t m a
```
I wondered if this works with GND. As it turns out, the answer is yes:
```haskell
newtype B t (m :: Type > Type) a => B (t m a)
deriving (Functor, Applicative, Monad)
 StandaloneDeriving just to be sure the constraints is
 what I expect.
deriving instance MonadTrans t => MonadTrans (B t)
```
compiles just fine. But a conceptually very similar idea does not:
```haskell
class MonadTrans t where
lift :: m a > t m a
liftMonad :: Monad m => Proxy (t m) > (Monad (t m) => r) > r
```
This one produces an error,
```
Lift.hs:9:42: error:
• Occurs check: cannot construct the infinite type: t ~ B t
arising from the coercion of the method ‘liftMonad’
from type ‘forall (m :: * > *) r.
Monad m =>
Proxy (t m) > (Monad (t m) => r) > r’
to type ‘forall (m :: * > *) r.
Monad m =>
Proxy (B t m) > (Monad (B t m) => r) > r’
• When deriving the instance for (MonadTrans (B t))
```
Why does one work and not the other? Is there a good reason for that, or should they both succeed or both fail?https://gitlab.haskell.org/ghc/ghc//issues/19906Should Generically (/ Generically1) derive newtype Generic (/ Generic1)?20210530T15:01:27ZIcelandjackShould Generically (/ Generically1) derive newtype Generic (/ Generic1)?Regarding #17147 (!5726), this may be controversial and touch on the philosophy of Generic. "Generic" is universally derived using the *stock* deriving strategy. I propose deriving those instances for `Generically{,1}` using generalized *newtype* deriving, by reusing the underlying `Generic{,1}` instances. This is in line with all other instances for `Generically{,1}` as they are defined using the generic representation of the underlying type.
```haskell
type Generically :: Type > Type
newtype Generically a = Generically a
deriving
newtype Generic
type Generically1 :: (k > Type) > k > Type
newtype Generically1 f a = Generically1 (f a)
deriving
newtype Generic1
```
That is to say be given the following instance
```haskell
instance Generic a => Generic (Generically a) where
type Rep (Generically a) = Rep a
from :: Generically a > Rep a b
from (Generically a) = from a
to :: Rep a b > Generically a
to = Generically . to
instance Generic1 f => Generic1 (Generically1 f) where
type Rep1 (Generically1 f) = Rep1 f
from1 :: Generically1 f a > Rep1 f a
from1 (Generically1 as) = from1 as
to1 :: Rep1 f a > Generically1 f a
to1 = Generically1 . to1
```
The other instances avoid newtype wrapping
```haskell
Generically a <> Generically b = Generically (to (from a <> from b :: Rep a ()))
mempty = Generically (to (mempty :: Rep a ()))
fmap f (Generically1 as) = Generically1 (to1 (fmap f (from1 as)))
a <$ Generically1 as = Generically1 (to1 (a <$ from1 as))
pure a = Generically1 (to1 (pure a))
Generically1 fs <*> Generically1 as = Generically1 (to1 (from1 fs <*> from1 as))
liftA2 (·) (Generically1 as) (Generically1 bs) = Generically1 (to1 (liftA2 (·) (from1 as) (from1 bs)))
empty = Generically1 (to1 empty)
Generically1 as1 <> Generically1 as2 = Generically1 (to1 (from1 as1 <> from1 as2))
```
>
```haskell
a <> b = to (from a <> from b :: Rep a ())
mempty = to (mempty :: Rep a ())
fmap f = to1 . fmap f . from1
a <$ as = to1 (a <$ from1 as)
pure = to1 . pure
fs <*> as = to1 (from1 fs <*> from1 as)
liftA2 (·) as bs = to1 (liftA2 (·) (from1 as) (from1 bs))
empty = to1 empty
as1 <> as2 = to1 (from1 as1 <> from1 as2)
```Regarding #17147 (!5726), this may be controversial and touch on the philosophy of Generic. "Generic" is universally derived using the *stock* deriving strategy. I propose deriving those instances for `Generically{,1}` using generalized *newtype* deriving, by reusing the underlying `Generic{,1}` instances. This is in line with all other instances for `Generically{,1}` as they are defined using the generic representation of the underlying type.
```haskell
type Generically :: Type > Type
newtype Generically a = Generically a
deriving
newtype Generic
type Generically1 :: (k > Type) > k > Type
newtype Generically1 f a = Generically1 (f a)
deriving
newtype Generic1
```
That is to say be given the following instance
```haskell
instance Generic a => Generic (Generically a) where
type Rep (Generically a) = Rep a
from :: Generically a > Rep a b
from (Generically a) = from a
to :: Rep a b > Generically a
to = Generically . to
instance Generic1 f => Generic1 (Generically1 f) where
type Rep1 (Generically1 f) = Rep1 f
from1 :: Generically1 f a > Rep1 f a
from1 (Generically1 as) = from1 as
to1 :: Rep1 f a > Generically1 f a
to1 = Generically1 . to1
```
The other instances avoid newtype wrapping
```haskell
Generically a <> Generically b = Generically (to (from a <> from b :: Rep a ()))
mempty = Generically (to (mempty :: Rep a ()))
fmap f (Generically1 as) = Generically1 (to1 (fmap f (from1 as)))
a <$ Generically1 as = Generically1 (to1 (a <$ from1 as))
pure a = Generically1 (to1 (pure a))
Generically1 fs <*> Generically1 as = Generically1 (to1 (from1 fs <*> from1 as))
liftA2 (·) (Generically1 as) (Generically1 bs) = Generically1 (to1 (liftA2 (·) (from1 as) (from1 bs)))
empty = Generically1 (to1 empty)
Generically1 as1 <> Generically1 as2 = Generically1 (to1 (from1 as1 <> from1 as2))
```
>
```haskell
a <> b = to (from a <> from b :: Rep a ())
mempty = to (mempty :: Rep a ())
fmap f = to1 . fmap f . from1
a <$ as = to1 (a <$ from1 as)
pure = to1 . pure
fs <*> as = to1 (from1 fs <*> from1 as)
liftA2 (·) as bs = to1 (liftA2 (·) (from1 as) (from1 bs))
empty = to1 empty
as1 <> as2 = to1 (from1 as1 <> from1 as2)
```https://gitlab.haskell.org/ghc/ghc//issues/19786DerivingVia is considered Safe20210513T14:06:06ZOleg GrenrusDerivingVia is considered Safe... but GND isn't!
```haskell
{# LANGUAGE Safe #}
{# LANGUAGE DerivingVia #}
module Via where
newtype Down a = Down a
instance Eq a => Eq (Down a) where
Down x == Down y = x == y
instance Ord a => Ord (Down a) where
compare (Down x) (Down y) = compare y x
newtype Foo = Foo (Down Int)
deriving stock Eq
deriving Ord via Down Int
```
compiles.
With `ghc9.0.1 ddumphi Via.hs fforcerecomp`
```
...
trusted: safe
...
```
and no warnings or errors.... but GND isn't!
```haskell
{# LANGUAGE Safe #}
{# LANGUAGE DerivingVia #}
module Via where
newtype Down a = Down a
instance Eq a => Eq (Down a) where
Down x == Down y = x == y
instance Ord a => Ord (Down a) where
compare (Down x) (Down y) = compare y x
newtype Foo = Foo (Down Int)
deriving stock Eq
deriving Ord via Down Int
```
compiles.
With `ghc9.0.1 ddumphi Via.hs fforcerecomp`
```
...
trusted: safe
...
```
and no warnings or errors.https://gitlab.haskell.org/ghc/ghc//issues/8827Inferring Safe mode with GeneralizedNewtypeDeriving is wrong20210503T15:12:10ZRichard Eisenbergrae@richarde.devInferring Safe mode with GeneralizedNewtypeDeriving is wrongSee a detailed write up here [SafeHaskell,GNDandRoles](saferoles)
Consider the following modules:
```
module A (List, ints) where
data List a = Nil  Cons a (List a)
infixr 4 `Cons`
ints :: List Int
ints = 1 `Cons` 2 `Cons` 3 `Cons` Nil
```
```
{# LANGUAGE GeneralizedNewtypeDeriving #}
module B where
import A
newtype Age = MkAge Int
deriving C
class C a where
cList :: List a
instance C Int where
cList = ints
```
```
{# LANGUAGE Safe #}
module C (ages) where
import A
import B
ages :: List Age
ages = cList
```
Module C compiles without a hiccup. But, it shouldn't: the coercion between `ages` and `ints` (performed by !GeneralizedNewtypeDeriving in module B) isn't Safe, as it breaks through `List`'s abstraction. (Note that the constructors of `List` are *not* exported from module A!)
If module B includes `{# LANGUAGE Safe #}`, it duly doesn't compile, because of the stringent "constructorsmustbeinscope" check done by the `Coercible` mechanism. The problem is that safety can be *inferred* without this check taking place.
You may also want to read the commentary on #8745 for related discussion.See a detailed write up here [SafeHaskell,GNDandRoles](saferoles)
Consider the following modules:
```
module A (List, ints) where
data List a = Nil  Cons a (List a)
infixr 4 `Cons`
ints :: List Int
ints = 1 `Cons` 2 `Cons` 3 `Cons` Nil
```
```
{# LANGUAGE GeneralizedNewtypeDeriving #}
module B where
import A
newtype Age = MkAge Int
deriving C
class C a where
cList :: List a
instance C Int where
cList = ints
```
```
{# LANGUAGE Safe #}
module C (ages) where
import A
import B
ages :: List Age
ages = cList
```
Module C compiles without a hiccup. But, it shouldn't: the coercion between `ages` and `ints` (performed by !GeneralizedNewtypeDeriving in module B) isn't Safe, as it breaks through `List`'s abstraction. (Note that the constructors of `List` are *not* exported from module A!)
If module B includes `{# LANGUAGE Safe #}`, it duly doesn't compile, because of the stringent "constructorsmustbeinscope" check done by the `Coercible` mechanism. The problem is that safety can be *inferred* without this check taking place.
You may also want to read the commentary on #8745 for related discussion.8.0.1https://gitlab.haskell.org/ghc/ghc//issues/19713DeriveFunctor: Use `contramap' in contravariant position20210419T03:44:35ZIcelandjackDeriveFunctor: Use `contramap' in contravariant positionThis rule for [*cofmap* in `GHC.Tc.Deriv.Functor`](https://gitlab.haskell.org/ghc/ghc//blob/master/compiler/GHC/Tc/Deriv/Functor.hs#L111) can not deal with a type variable in contravariant position
```
$(cofmap 'a 'b x) = x  when b does not contain a
$(cofmap 'a 'a x) = error "type variable in contravariant position"
$(cofmap 'a '(b1,b2) x) = case x of (x1,x2) > ($(cofmap 'a 'b1) x1, $(cofmap 'a 'b2) x2)
$(cofmap 'a '(T b1 a) x) = error "type variable in contravariant position"  when a only occurs directly as the last argument of T
$(cofmap 'a '(T b1 b2) x) = fmap (\y. $(cofmap 'a 'b2 y)) x  when a only occurs in the last parameter, b2
$(cofmap 'a '(tb > tc) x) = \(y:tb[b/a]) > $(cofmap 'a' 'tc' (x $(fmap 'a 'tb y)))
```
but now that we have `Data.Functor.Contravariant` in base why not generate an invocation to `contramap`?
```
$(cofmap 'a '(T b1 a) x) = contramap f x
```
As an example, this works becuase of the special case for functions
```
> :set XDerivingStrategies XDeriveFunctor
> newtype F a = MkF ((a > Int) > Int) deriving stock Functor
```
but if we use `Op Int a` (which is a newtype wrapping `a > Int`) ghc does not know how to derive it.
```
> newtype F a = MkF (Op Int a > Int) deriving stock Functor
<interactive>:10:52: error:
• Can't make a derived instance of
‘Functor F’ with the stock strategy:
Constructor ‘MkF’ must not use the type variable in a function argument
• In the newtype declaration for ‘F’
```
I claim it should work by inserting a `contramap` invocation there so both these definitions
```haskell
newtype F a = MkF (Op Int a > Int) deriving stock Functor
newtype F a = MkF (Equivalence a > Int) deriving stock Functor
```
would generate the following (basically)
```haskell
instance Functor F where
fmap :: (a > a') > (F a > F a')
fmap f (MkF as) = MkF (fmap as (contramap f))
```This rule for [*cofmap* in `GHC.Tc.Deriv.Functor`](https://gitlab.haskell.org/ghc/ghc//blob/master/compiler/GHC/Tc/Deriv/Functor.hs#L111) can not deal with a type variable in contravariant position
```
$(cofmap 'a 'b x) = x  when b does not contain a
$(cofmap 'a 'a x) = error "type variable in contravariant position"
$(cofmap 'a '(b1,b2) x) = case x of (x1,x2) > ($(cofmap 'a 'b1) x1, $(cofmap 'a 'b2) x2)
$(cofmap 'a '(T b1 a) x) = error "type variable in contravariant position"  when a only occurs directly as the last argument of T
$(cofmap 'a '(T b1 b2) x) = fmap (\y. $(cofmap 'a 'b2 y)) x  when a only occurs in the last parameter, b2
$(cofmap 'a '(tb > tc) x) = \(y:tb[b/a]) > $(cofmap 'a' 'tc' (x $(fmap 'a 'tb y)))
```
but now that we have `Data.Functor.Contravariant` in base why not generate an invocation to `contramap`?
```
$(cofmap 'a '(T b1 a) x) = contramap f x
```
As an example, this works becuase of the special case for functions
```
> :set XDerivingStrategies XDeriveFunctor
> newtype F a = MkF ((a > Int) > Int) deriving stock Functor
```
but if we use `Op Int a` (which is a newtype wrapping `a > Int`) ghc does not know how to derive it.
```
> newtype F a = MkF (Op Int a > Int) deriving stock Functor
<interactive>:10:52: error:
• Can't make a derived instance of
‘Functor F’ with the stock strategy:
Constructor ‘MkF’ must not use the type variable in a function argument
• In the newtype declaration for ‘F’
```
I claim it should work by inserting a `contramap` invocation there so both these definitions
```haskell
newtype F a = MkF (Op Int a > Int) deriving stock Functor
newtype F a = MkF (Equivalence a > Int) deriving stock Functor
```
would generate the following (basically)
```haskell
instance Functor F where
fmap :: (a > a') > (F a > F a')
fmap f (MkF as) = MkF (fmap as (contramap f))
```https://gitlab.haskell.org/ghc/ghc//issues/19707[Discussion] Integrating DataTypeable, Functor, Foldable, Traversable, Generi...20210416T06:48:14ZHécate Moonlight[Discussion] Integrating DataTypeable, Functor, Foldable, Traversable, Generic and Lift in the `stock` deriving strategyI wish to start a discussion around the possibility of integrating the numerous classes we offer in `base` in the `stock` deriving strategy by the removing the need to use language extensions to expose them to enduser.
This ticket is not meant to bypass a proper GHC Proposal, but I'd like to get some feedback from the GHC dev team and adjacent folks before starting a proposal process.
I personally think we may have reached the maturity where it would make sense to greatly simplify this aspect of the compiler, but I am not omniscient and clearly could use different perspectives. :)

Note: Matt Parsons has also raised this question in his article [Haskell Proposal: Simplify Deriving](https://www.parsonsmatt.org/2020/11/10/simplifying_deriving.html).I wish to start a discussion around the possibility of integrating the numerous classes we offer in `base` in the `stock` deriving strategy by the removing the need to use language extensions to expose them to enduser.
This ticket is not meant to bypass a proper GHC Proposal, but I'd like to get some feedback from the GHC dev team and adjacent folks before starting a proposal process.
I personally think we may have reached the maturity where it would make sense to greatly simplify this aspect of the compiler, but I am not omniscient and clearly could use different perspectives. :)

Note: Matt Parsons has also raised this question in his article [Haskell Proposal: Simplify Deriving](https://www.parsonsmatt.org/2020/11/10/simplifying_deriving.html).https://gitlab.haskell.org/ghc/ghc//issues/19692Don't suggest turning on `DeriveAnyClass` when an instance cannot be derived20210415T08:02:55Zsyd@cssyd.euDon't suggest turning on `DeriveAnyClass` when an instance cannot be derived## Summary
Location of documentation issue: GHC Error Message
Given this example:
```
class MyClass a where
myFunc :: a > Int
data MyExample = MyExample {myBool :: Bool, myInt :: Int}
deriving (Show, Eq, MyClass)
```
GHC (correctly) rejects this with this error:
```
example.hs:5:23: error:
• Can't make a derived instance of ‘MyClass MyExample’:
‘MyClass’ is not a stock derivable class (Eq, Show, etc.)
Try enabling DeriveAnyClass
• In the data declaration for ‘MyExample’

5  deriving (Show, Eq, MyClass)

```
However, it's suggestion to `Try enabling DeriveAnyClass` is not great, because when one does that:
```
{# LANGUAGE DeriveAnyClass #}
class MyClass a where
myFunc :: a > Int
data MyExample = MyExample {myBool :: Bool, myInt :: Int}
deriving (Show, Eq, MyClass)
```
GHC now (incorrectly, IMHO), accepts this with the following warning:
(At least there is a warning, there didn't use to be, right?)
```
example.hs:7:23: warning: [Wmissingmethods]
• No explicit implementation for
‘myFunc’
• In the instance declaration for ‘MyClass MyExample’

7  deriving (Show, Eq, MyClass)

```
However, this fails at runtime (!):
```
*Main> myFunc (MyExample {myBool =True,myInt =5})
*** Exception: example.hs:7:2329: No instance nor default method for class operation myFunc
```
## Proposed improvements or changes
Don't suggest enabling `DeriveAnyClass`.
Optional: Give a much more comprehensive recommendation that doesn't lead users to write code that throws runtime exceptions in pure code.## Summary
Location of documentation issue: GHC Error Message
Given this example:
```
class MyClass a where
myFunc :: a > Int
data MyExample = MyExample {myBool :: Bool, myInt :: Int}
deriving (Show, Eq, MyClass)
```
GHC (correctly) rejects this with this error:
```
example.hs:5:23: error:
• Can't make a derived instance of ‘MyClass MyExample’:
‘MyClass’ is not a stock derivable class (Eq, Show, etc.)
Try enabling DeriveAnyClass
• In the data declaration for ‘MyExample’

5  deriving (Show, Eq, MyClass)

```
However, it's suggestion to `Try enabling DeriveAnyClass` is not great, because when one does that:
```
{# LANGUAGE DeriveAnyClass #}
class MyClass a where
myFunc :: a > Int
data MyExample = MyExample {myBool :: Bool, myInt :: Int}
deriving (Show, Eq, MyClass)
```
GHC now (incorrectly, IMHO), accepts this with the following warning:
(At least there is a warning, there didn't use to be, right?)
```
example.hs:7:23: warning: [Wmissingmethods]
• No explicit implementation for
‘myFunc’
• In the instance declaration for ‘MyClass MyExample’

7  deriving (Show, Eq, MyClass)

```
However, this fails at runtime (!):
```
*Main> myFunc (MyExample {myBool =True,myInt =5})
*** Exception: example.hs:7:2329: No instance nor default method for class operation myFunc
```
## Proposed improvements or changes
Don't suggest enabling `DeriveAnyClass`.
Optional: Give a much more comprehensive recommendation that doesn't lead users to write code that throws runtime exceptions in pure code.https://gitlab.haskell.org/ghc/ghc//issues/5642Deriving Generic of a big type takes a long time and lots of space20210414T16:02:48ZbasvandijkDeriving Generic of a big type takes a long time and lots of spaceIf I load the following module into `ghci` my system will run out of memory after about 15 minutes:
```
{# LANGUAGE DeriveGeneric #}
import GHC.Generics
data BigSum =
C0  C1  C2  C3  C4  C5  C6  C7  C8  C9
 C10  C11  C12  C13  C14  C15  C16  C17  C18  C19
 C20  C21  C22  C23  C24  C25  C26  C27  C28  C29
 C30  C31  C32  C33  C34  C35  C36  C37  C38  C39
 C40  C41  C42  C43  C44  C45  C46  C47  C48  C49
 C50  C51  C52  C53  C54  C55  C56  C57  C58  C59
 C60  C61  C62  C63  C64  C65  C66  C67  C68  C69
 C70  C71  C72  C73  C74  C75  C76  C77  C78  C79
 C80  C81  C82  C83  C84  C85  C86  C87  C88  C89
 C90  C91  C92  C93  C94  C95  C96  C97  C98  C99
 C100  C101  C102  C103  C104  C105  C106  C107  C108  C109
 C110  C111  C112  C113  C114  C115  C116  C117  C118  C119
 C120  C121  C122  C123  C124  C125  C126  C127  C128  C129
 C130  C131  C132  C133  C134  C135  C136  C137  C138  C139
 C140  C141  C142  C143  C144  C145  C146  C147  C148  C149
 C150  C151  C152  C153  C154  C155  C156  C157  C158  C159
 C160  C161  C162  C163  C164  C165  C166  C167  C168  C169
 C170  C171  C172  C173  C174  C175  C176  C177  C178  C179
 C180  C181  C182  C183  C184  C185  C186  C187  C188  C189
 C190  C191  C192  C193  C194  C195  C196  C197  C198  C199
 C200  C201  C202  C203  C204  C205  C206  C207  C208  C209
 C210  C211  C212  C213  C214  C215  C216  C217  C218  C219
 C220  C221  C222  C223  C224  C225  C226  C227  C228  C229
 C230  C231  C232  C233  C234  C235  C236  C237  C238  C239
 C240  C241  C242  C243  C244  C245  C246  C247  C248  C249
 C250  C251  C252  C253  C254  C255  C256  C257  C258  C259
 C260  C261  C262  C263  C264  C265  C266  C267  C268  C269
 C270  C271  C272  C273  C274  C275  C276  C277  C278  C279
 C280  C281  C282  C283  C284  C285  C286  C287  C288  C289
 C290  C291  C292  C293  C294  C295  C296  C297  C298  C299
deriving Generic
```
Big products have the same problem:
```
data BigProduct = C
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
deriving Generic
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  7.2.1 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  dreixel 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Deriving Generic of a big type takes a long time and lots of space","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["dreixel"],"type":"Bug","description":"If I load the following module into `ghci` my system will run out of memory after about 15 minutes: \r\n\r\n{{{\r\n{# LANGUAGE DeriveGeneric #}\r\n\r\nimport GHC.Generics\r\n\r\ndata BigSum = \r\n C0  C1  C2  C3  C4  C5  C6  C7  C8  C9 \r\n  C10  C11  C12  C13  C14  C15  C16  C17  C18  C19 \r\n  C20  C21  C22  C23  C24  C25  C26  C27  C28  C29\r\n  C30  C31  C32  C33  C34  C35  C36  C37  C38  C39\r\n  C40  C41  C42  C43  C44  C45  C46  C47  C48  C49\r\n  C50  C51  C52  C53  C54  C55  C56  C57  C58  C59\r\n  C60  C61  C62  C63  C64  C65  C66  C67  C68  C69\r\n  C70  C71  C72  C73  C74  C75  C76  C77  C78  C79\r\n  C80  C81  C82  C83  C84  C85  C86  C87  C88  C89\r\n  C90  C91  C92  C93  C94  C95  C96  C97  C98  C99\r\n  C100  C101  C102  C103  C104  C105  C106  C107  C108  C109\r\n  C110  C111  C112  C113  C114  C115  C116  C117  C118  C119\r\n  C120  C121  C122  C123  C124  C125  C126  C127  C128  C129\r\n  C130  C131  C132  C133  C134  C135  C136  C137  C138  C139\r\n  C140  C141  C142  C143  C144  C145  C146  C147  C148  C149\r\n  C150  C151  C152  C153  C154  C155  C156  C157  C158  C159\r\n  C160  C161  C162  C163  C164  C165  C166  C167  C168  C169\r\n  C170  C171  C172  C173  C174  C175  C176  C177  C178  C179\r\n  C180  C181  C182  C183  C184  C185  C186  C187  C188  C189\r\n  C190  C191  C192  C193  C194  C195  C196  C197  C198  C199\r\n  C200  C201  C202  C203  C204  C205  C206  C207  C208  C209\r\n  C210  C211  C212  C213  C214  C215  C216  C217  C218  C219\r\n  C220  C221  C222  C223  C224  C225  C226  C227  C228  C229\r\n  C230  C231  C232  C233  C234  C235  C236  C237  C238  C239\r\n  C240  C241  C242  C243  C244  C245  C246  C247  C248  C249\r\n  C250  C251  C252  C253  C254  C255  C256  C257  C258  C259\r\n  C260  C261  C262  C263  C264  C265  C266  C267  C268  C269\r\n  C270  C271  C272  C273  C274  C275  C276  C277  C278  C279\r\n  C280  C281  C282  C283  C284  C285  C286  C287  C288  C289\r\n  C290  C291  C292  C293  C294  C295  C296  C297  C298  C299\r\n deriving Generic\r\n}}}\r\n\r\nBig products have the same problem:\r\n\r\n{{{\r\ndata BigProduct = C \r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n deriving Generic\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} >If I load the following module into `ghci` my system will run out of memory after about 15 minutes:
```
{# LANGUAGE DeriveGeneric #}
import GHC.Generics
data BigSum =
C0  C1  C2  C3  C4  C5  C6  C7  C8  C9
 C10  C11  C12  C13  C14  C15  C16  C17  C18  C19
 C20  C21  C22  C23  C24  C25  C26  C27  C28  C29
 C30  C31  C32  C33  C34  C35  C36  C37  C38  C39
 C40  C41  C42  C43  C44  C45  C46  C47  C48  C49
 C50  C51  C52  C53  C54  C55  C56  C57  C58  C59
 C60  C61  C62  C63  C64  C65  C66  C67  C68  C69
 C70  C71  C72  C73  C74  C75  C76  C77  C78  C79
 C80  C81  C82  C83  C84  C85  C86  C87  C88  C89
 C90  C91  C92  C93  C94  C95  C96  C97  C98  C99
 C100  C101  C102  C103  C104  C105  C106  C107  C108  C109
 C110  C111  C112  C113  C114  C115  C116  C117  C118  C119
 C120  C121  C122  C123  C124  C125  C126  C127  C128  C129
 C130  C131  C132  C133  C134  C135  C136  C137  C138  C139
 C140  C141  C142  C143  C144  C145  C146  C147  C148  C149
 C150  C151  C152  C153  C154  C155  C156  C157  C158  C159
 C160  C161  C162  C163  C164  C165  C166  C167  C168  C169
 C170  C171  C172  C173  C174  C175  C176  C177  C178  C179
 C180  C181  C182  C183  C184  C185  C186  C187  C188  C189
 C190  C191  C192  C193  C194  C195  C196  C197  C198  C199
 C200  C201  C202  C203  C204  C205  C206  C207  C208  C209
 C210  C211  C212  C213  C214  C215  C216  C217  C218  C219
 C220  C221  C222  C223  C224  C225  C226  C227  C228  C229
 C230  C231  C232  C233  C234  C235  C236  C237  C238  C239
 C240  C241  C242  C243  C244  C245  C246  C247  C248  C249
 C250  C251  C252  C253  C254  C255  C256  C257  C258  C259
 C260  C261  C262  C263  C264  C265  C266  C267  C268  C269
 C270  C271  C272  C273  C274  C275  C276  C277  C278  C279
 C280  C281  C282  C283  C284  C285  C286  C287  C288  C289
 C290  C291  C292  C293  C294  C295  C296  C297  C298  C299
deriving Generic
```
Big products have the same problem:
```
data BigProduct = C
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
deriving Generic
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  7.2.1 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  dreixel 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Deriving Generic of a big type takes a long time and lots of space","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["dreixel"],"type":"Bug","description":"If I load the following module into `ghci` my system will run out of memory after about 15 minutes: \r\n\r\n{{{\r\n{# LANGUAGE DeriveGeneric #}\r\n\r\nimport GHC.Generics\r\n\r\ndata BigSum = \r\n C0  C1  C2  C3  C4  C5  C6  C7  C8  C9 \r\n  C10  C11  C12  C13  C14  C15  C16  C17  C18  C19 \r\n  C20  C21  C22  C23  C24  C25  C26  C27  C28  C29\r\n  C30  C31  C32  C33  C34  C35  C36  C37  C38  C39\r\n  C40  C41  C42  C43  C44  C45  C46  C47  C48  C49\r\n  C50  C51  C52  C53  C54  C55  C56  C57  C58  C59\r\n  C60  C61  C62  C63  C64  C65  C66  C67  C68  C69\r\n  C70  C71  C72  C73  C74  C75  C76  C77  C78  C79\r\n  C80  C81  C82  C83  C84  C85  C86  C87  C88  C89\r\n  C90  C91  C92  C93  C94  C95  C96  C97  C98  C99\r\n  C100  C101  C102  C103  C104  C105  C106  C107  C108  C109\r\n  C110  C111  C112  C113  C114  C115  C116  C117  C118  C119\r\n  C120  C121  C122  C123  C124  C125  C126  C127  C128  C129\r\n  C130  C131  C132  C133  C134  C135  C136  C137  C138  C139\r\n  C140  C141  C142  C143  C144  C145  C146  C147  C148  C149\r\n  C150  C151  C152  C153  C154  C155  C156  C157  C158  C159\r\n  C160  C161  C162  C163  C164  C165  C166  C167  C168  C169\r\n  C170  C171  C172  C173  C174  C175  C176  C177  C178  C179\r\n  C180  C181  C182  C183  C184  C185  C186  C187  C188  C189\r\n  C190  C191  C192  C193  C194  C195  C196  C197  C198  C199\r\n  C200  C201  C202  C203  C204  C205  C206  C207  C208  C209\r\n  C210  C211  C212  C213  C214  C215  C216  C217  C218  C219\r\n  C220  C221  C222  C223  C224  C225  C226  C227  C228  C229\r\n  C230  C231  C232  C233  C234  C235  C236  C237  C238  C239\r\n  C240  C241  C242  C243  C244  C245  C246  C247  C248  C249\r\n  C250  C251  C252  C253  C254  C255  C256  C257  C258  C259\r\n  C260  C261  C262  C263  C264  C265  C266  C267  C268  C269\r\n  C270  C271  C272  C273  C274  C275  C276  C277  C278  C279\r\n  C280  C281  C282  C283  C284  C285  C286  C287  C288  C289\r\n  C290  C291  C292  C293  C294  C295  C296  C297  C298  C299\r\n deriving Generic\r\n}}}\r\n\r\nBig products have the same problem:\r\n\r\n{{{\r\ndata BigProduct = C \r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n () () () () () () () () () ()\r\n deriving Generic\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} >9.2.1https://gitlab.haskell.org/ghc/ghc//issues/19445(Derived) Ord instances generate terrible code20210402T02:31:57ZSebastian Graf(Derived) Ord instances generate terrible codeConsider these attempts at coming up with more compact `compare` functions:
```hs
{# OPTIONS_GHC O2 fforcerecomp #}
{# LANGUAGE TypeApplications #}
{# LANGUAGE BangPatterns #}
{# LANGUAGE MagicHash #}
module Lib (foo, bar, baz) where
import GHC.Exts
import GHC.Classes
data U = U Int deriving Eq
instance Ord U where
 so that this function isn't WW'd
compare ~(U a) ~(U b) = lazy $ compare a b
{# NOINLINE compare #}
data T
= T0 U
 T1 U
 T2 U
 T3 U
 T4 U
 T5 U
deriving (Eq, Ord)
foo :: T > T > Ordering
foo = compare @T
bar :: T > T > Ordering
bar !_ r  !_ < dataToTag# r, id False = undefined
bar (T0 a1) (T0 a2) = compare a1 a2
bar (T1 a1) (T1 a2) = compare a1 a2
bar (T2 a1) (T2 a2) = compare a1 a2
bar (T3 a1) (T3 a2) = compare a1 a2
bar (T4 a1) (T4 a2) = compare a1 a2
bar (T5 a1) (T5 a2) = compare a1 a2
bar l r
 isTrue# (dataToTag# l <# dataToTag# r) = LT
 otherwise = GT
baz :: T > T > Ordering
baz l r = compareInt# (dataToTag# l) (dataToTag# r) <> go l r
where
go (T0 a1) (T0 a2) = compare a1 a2
go (T1 a1) (T1 a2) = compare a1 a2
go (T2 a1) (T2 a2) = compare a1 a2
go (T3 a1) (T3 a2) = compare a1 a2
go (T4 a1) (T4 a2) = compare a1 a2
go (T5 a1) (T5 a2) = compare a1 a2
```
`bar` speculates `dataToTag#` on the second argument, so that its result is shared among all case branches. `baz` goes a step further: It simply compares tags and only compares fields when the tags match.
Here's the generated Core for the `T3` case:
```
foo a b_aLh = case a of {
T3 a1_aLp >
case dataToTag# @T b_aLh of b#_aLq { __DEFAULT >
case <# b#_aLq 3# of {
__DEFAULT >
case b_aLh of {
__DEFAULT > GHC.Types.LT;
T3 b1_aLr > Lib.foo_$ccompare a1_aLp b1_aLr
};
1# > GHC.Types.GT
}
}
}
bar a b_aLh =
case dataToTag# @T b_aLh of ds1_dU3 { __DEFAULT >
case a of {
T3 a1_aJb >
case b_aLh of {
__DEFAULT >
case <# 3# ds1_dU3 of {
__DEFAULT > GHC.Types.GT;
1# > GHC.Types.LT
};
T3 a2_aJc > Lib.foo_$ccompare a1_aJb a2_aJc
};
}
}
baz l_aJj r_aJk =
case dataToTag# @T r_aJk of wild_X1 { __DEFAULT >
case dataToTag# @T l_aJj of wild1_X2 { __DEFAULT >
case <# wild1_X2 wild_X1 of {
1# > GHC.Types.LT;
__DEFAULT >
case ==# wild1_X2 wild_X1 of {
__DEFAULT > GHC.Types.GT;
1# >
case l_aJj of {
T3 a1_aJs >
case r_aJk of {
__DEFAULT > Lib.baz1;  pattern match error thunk
T3 a2_aJt > Lib.foo_$ccompare a1_aJs a2_aJt
};
}
}
}
```
That is I think about the Core I'd expect, with one exception: I'd hoped that GHC would detect that the pattern match error in `baz` is impossible, which it doesn't.
Although `baz` looks rather big, I expected most of it to lower to very simple instructions. Well, `nm printsize sizesort test.o` reveals:
```
0000000000001180 000000000000032f T Lib_bar_info
0000000000000b00 0000000000000373 T Lib_foo_info
00000000000014c8 000000000000038f T Lib_bazz_info
```
So `bar` is a bit smaller than `foo` (the stock derived function), while `baz` is larger. All of them are quite large: They range between 0x300 (768) and 0x400 (1024) bytes!
I had a cursory look at the Cmm, and I was lost almost instantly. That was due to #19444, I think.
It's surely possible to generate more compact code for derived `Ord` instances. It's so common, yet so much more inefficient to do the equivalent in C!Consider these attempts at coming up with more compact `compare` functions:
```hs
{# OPTIONS_GHC O2 fforcerecomp #}
{# LANGUAGE TypeApplications #}
{# LANGUAGE BangPatterns #}
{# LANGUAGE MagicHash #}
module Lib (foo, bar, baz) where
import GHC.Exts
import GHC.Classes
data U = U Int deriving Eq
instance Ord U where
 so that this function isn't WW'd
compare ~(U a) ~(U b) = lazy $ compare a b
{# NOINLINE compare #}
data T
= T0 U
 T1 U
 T2 U
 T3 U
 T4 U
 T5 U
deriving (Eq, Ord)
foo :: T > T > Ordering
foo = compare @T
bar :: T > T > Ordering
bar !_ r  !_ < dataToTag# r, id False = undefined
bar (T0 a1) (T0 a2) = compare a1 a2
bar (T1 a1) (T1 a2) = compare a1 a2
bar (T2 a1) (T2 a2) = compare a1 a2
bar (T3 a1) (T3 a2) = compare a1 a2
bar (T4 a1) (T4 a2) = compare a1 a2
bar (T5 a1) (T5 a2) = compare a1 a2
bar l r
 isTrue# (dataToTag# l <# dataToTag# r) = LT
 otherwise = GT
baz :: T > T > Ordering
baz l r = compareInt# (dataToTag# l) (dataToTag# r) <> go l r
where
go (T0 a1) (T0 a2) = compare a1 a2
go (T1 a1) (T1 a2) = compare a1 a2
go (T2 a1) (T2 a2) = compare a1 a2
go (T3 a1) (T3 a2) = compare a1 a2
go (T4 a1) (T4 a2) = compare a1 a2
go (T5 a1) (T5 a2) = compare a1 a2
```
`bar` speculates `dataToTag#` on the second argument, so that its result is shared among all case branches. `baz` goes a step further: It simply compares tags and only compares fields when the tags match.
Here's the generated Core for the `T3` case:
```
foo a b_aLh = case a of {
T3 a1_aLp >
case dataToTag# @T b_aLh of b#_aLq { __DEFAULT >
case <# b#_aLq 3# of {
__DEFAULT >
case b_aLh of {
__DEFAULT > GHC.Types.LT;
T3 b1_aLr > Lib.foo_$ccompare a1_aLp b1_aLr
};
1# > GHC.Types.GT
}
}
}
bar a b_aLh =
case dataToTag# @T b_aLh of ds1_dU3 { __DEFAULT >
case a of {
T3 a1_aJb >
case b_aLh of {
__DEFAULT >
case <# 3# ds1_dU3 of {
__DEFAULT > GHC.Types.GT;
1# > GHC.Types.LT
};
T3 a2_aJc > Lib.foo_$ccompare a1_aJb a2_aJc
};
}
}
baz l_aJj r_aJk =
case dataToTag# @T r_aJk of wild_X1 { __DEFAULT >
case dataToTag# @T l_aJj of wild1_X2 { __DEFAULT >
case <# wild1_X2 wild_X1 of {
1# > GHC.Types.LT;
__DEFAULT >
case ==# wild1_X2 wild_X1 of {
__DEFAULT > GHC.Types.GT;
1# >
case l_aJj of {
T3 a1_aJs >
case r_aJk of {
__DEFAULT > Lib.baz1;  pattern match error thunk
T3 a2_aJt > Lib.foo_$ccompare a1_aJs a2_aJt
};
}
}
}
```
That is I think about the Core I'd expect, with one exception: I'd hoped that GHC would detect that the pattern match error in `baz` is impossible, which it doesn't.
Although `baz` looks rather big, I expected most of it to lower to very simple instructions. Well, `nm printsize sizesort test.o` reveals:
```
0000000000001180 000000000000032f T Lib_bar_info
0000000000000b00 0000000000000373 T Lib_foo_info
00000000000014c8 000000000000038f T Lib_bazz_info
```
So `bar` is a bit smaller than `foo` (the stock derived function), while `baz` is larger. All of them are quite large: They range between 0x300 (768) and 0x400 (1024) bytes!
I had a cursory look at the Cmm, and I was lost almost instantly. That was due to #19444, I think.
It's surely possible to generate more compact code for derived `Ord` instances. It's so common, yet so much more inefficient to do the equivalent in C!https://gitlab.haskell.org/ghc/ghc//issues/13280Consider deriving more Foldable methods20210331T13:19:59ZDavid FeuerConsider deriving more Foldable methodsWe currently derive `foldMap` and `foldr`, but some others may deserve attention as well.
 The most critical spots are probably `length` and `null`. Deriving these instead of using the defaults can change the orders of growth! Given `data Tree a = Bin !(Tree a) a !(Tree a)  Tip`, we surely don't want `null` to traverse the whole spine of the tree when it's quite immediately obvious that `Bin` is never null. And if a constructor contains a type with a very efficient `length` or `null` implementation (e.g., one that stores its own size), we certainly want to use that.
 `foldl` typically ends up with rather different code than `foldr` (for a recursive type) even after simplification. We need to check whether this has a performance impact, but my bet is that it will in cases where the optimizer can't understand what's going on well enough.
 `foldl'` and `foldr'` are a bit tricky. Ideally, if we have something like `data T a = C (G a) a  ...` then we'd like to be able to use `G`'s `foldl'` definition to define `T`'s. Unfortunately, different types in the wild have different `foldl'` semantics (and indeed the semantics for `[]` changed by mistake fairly recently). So we have to decide to what extent the derived semantics should depend on the choices of included types. I think we should probably just depend, because that seems likely what people will expect and want.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Consider deriving more Foldable methods","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"We currently derive `foldMap` and `foldr`, but some others may deserve attention as well.\r\n\r\n* The most critical spots are probably `length` and `null`. Deriving these instead of using the defaults can change the orders of growth! Given `data Tree a = Bin !(Tree a) a !(Tree a)  Tip`, we surely don't want `null` to traverse the whole spine of the tree when it's quite immediately obvious that `Bin` is never null. And if a constructor contains a type with a very efficient `length` or `null` implementation (e.g., one that stores its own size), we certainly want to use that.\r\n\r\n* `foldl` typically ends up with rather different code than `foldr` (for a recursive type) even after simplification. We need to check whether this has a performance impact, but my bet is that it will in cases where the optimizer can't understand what's going on well enough.\r\n\r\n* `foldl'` and `foldr'` are a bit tricky. Ideally, if we have something like `data T a = C (G a) a  ...` then we'd like to be able to use `G`'s `foldl'` definition to define `T`'s. Unfortunately, different types in the wild have different `foldl'` semantics (and indeed the semantics for `[]` changed by mistake fairly recently). So we have to decide to what extent the derived semantics should depend on the choices of included types. I think we should probably just depend, because that seems likely what people will expect and want.","type_of_failure":"OtherFailure","blocking":[]} >We currently derive `foldMap` and `foldr`, but some others may deserve attention as well.
 The most critical spots are probably `length` and `null`. Deriving these instead of using the defaults can change the orders of growth! Given `data Tree a = Bin !(Tree a) a !(Tree a)  Tip`, we surely don't want `null` to traverse the whole spine of the tree when it's quite immediately obvious that `Bin` is never null. And if a constructor contains a type with a very efficient `length` or `null` implementation (e.g., one that stores its own size), we certainly want to use that.
 `foldl` typically ends up with rather different code than `foldr` (for a recursive type) even after simplification. We need to check whether this has a performance impact, but my bet is that it will in cases where the optimizer can't understand what's going on well enough.
 `foldl'` and `foldr'` are a bit tricky. Ideally, if we have something like `data T a = C (G a) a  ...` then we'd like to be able to use `G`'s `foldl'` definition to define `T`'s. Unfortunately, different types in the wild have different `foldl'` semantics (and indeed the semantics for `[]` changed by mistake fairly recently). So we have to decide to what extent the derived semantics should depend on the choices of included types. I think we should probably just depend, because that seems likely what people will expect and want.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.0.1 
 Type  Task 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Consider deriving more Foldable methods","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.2.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"We currently derive `foldMap` and `foldr`, but some others may deserve attention as well.\r\n\r\n* The most critical spots are probably `length` and `null`. Deriving these instead of using the defaults can change the orders of growth! Given `data Tree a = Bin !(Tree a) a !(Tree a)  Tip`, we surely don't want `null` to traverse the whole spine of the tree when it's quite immediately obvious that `Bin` is never null. And if a constructor contains a type with a very efficient `length` or `null` implementation (e.g., one that stores its own size), we certainly want to use that.\r\n\r\n* `foldl` typically ends up with rather different code than `foldr` (for a recursive type) even after simplification. We need to check whether this has a performance impact, but my bet is that it will in cases where the optimizer can't understand what's going on well enough.\r\n\r\n* `foldl'` and `foldr'` are a bit tricky. Ideally, if we have something like `data T a = C (G a) a  ...` then we'd like to be able to use `G`'s `foldl'` definition to define `T`'s. Unfortunately, different types in the wild have different `foldl'` semantics (and indeed the semantics for `[]` changed by mistake fairly recently). So we have to decide to what extent the derived semantics should depend on the choices of included types. I think we should probably just depend, because that seems likely what people will expect and want.","type_of_failure":"OtherFailure","blocking":[]} >David FeuerDavid Feuerhttps://gitlab.haskell.org/ghc/ghc//issues/19418Support overriding "No instance" errors using the default deriving strategy20210302T01:20:51Zinfinity0Support overriding "No instance" errors using the default deriving strategy## Motivation
Consider this code:
```haskell
data FooState a b c d = FooState
{ partA :: a
, partB :: b
, partC :: c
, partD :: d
}
deriving (Show, Read)
withFoo :: FooState a b c d > FooState a b c d
withFoo = undefined
```
Eugh, the API has 4 type params. This is confusing for users, especially when they combine it with other functions that take additional type params. In fact (a, b, c, d) are logically "our" (as the author of `FooState`) type params, so we can simplify it like this, by grouping them together:
```haskell
{# LANGUAGE TypeFamilies #}
class FooParams p where
type FooA p
type FooB p
type FooC p
type FooD p
data FooState' p = FooState'
{ partA :: FooA p
, partB :: FooB p
, partC :: FooC p
, partD :: FooD p
}
 deriving (Show, Read)  fails!
withFoo' :: FooParams p => FooState' p > FooState' p
withFoo' = undefined
```
<details>
<summary>(Alternatively, using more advanced language features you can even avoid the typeclass context, although this prevents you defining class methods on FooA etc, click for details)
</summary>
```haskell
{# LANGUAGE TypeFamilies, RankNTypes, PolyKinds, DataKinds, StandaloneKindSignatures #}
data FooParams aT bT cT dT = FooParams
{ fooA :: aT
, fooB :: bT
, fooC :: cT
, fooD :: dT
}
type FooA :: forall a b c d. FooParams a b c d > *
type family FooA p where FooA ('FooParams a b c d) = a
type FooB :: forall a b c d. FooParams a b c d > *
type family FooB p where FooB ('FooParams a b c d) = b
type FooC :: forall a b c d. FooParams a b c d > *
type family FooC p where FooC ('FooParams a b c d) = c
type FooD :: forall a b c d. FooParams a b c d > *
type family FooD p where FooD ('FooParams a b c d) = d
data FooState' (p :: FooParams a b c d) = FooState'
{ partA :: FooA p
, partB :: FooB p
, partC :: FooC p
, partD :: FooD p
}
 deriving (Show, Read)  fails!
withFoo' :: FooState' p > FooState' p
withFoo' = undefined
```
</details>
Either way, great, our API now only has 1 type param.
Unfortunately, now `deriving (Show, Read)` fails (in both examples):
~~~~
Test.hs:26:13: error:
• No instance for (Show (FooA p))
arising from the first field of ‘FooState'’ (type ‘FooA p’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Show (FooState' p))

26  deriving (Show, Read)
 ^^^^
Test.hs:26:19: error:
• No instance for (Read (FooA p))
arising from the first field of ‘FooState'’ (type ‘FooA p’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Read (FooState' p))

26  deriving (Show, Read)
 ^^^^
~~~~
We can currently work around this in 2 ways, neither of which is ideal:
<details>
<summary>standalone deriving, tedious manual context</summary>
```haskell
{# LANGUAGE TypeFamilies #}
{# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #}
class FooParams p where
type FooA p
type FooB p
type FooC p
type FooD p
data FooState' p = FooState'
{ partA :: FooA p
, partB :: FooB p
, partC :: FooC p
, partD :: FooD p
}
 manually supply the context, eugh
 increases n*m with number of associated types, and the number of extra instances e.g. Eq, Ord
deriving instance (Show (FooA p), Show (FooB p), Show (FooC p), Show (FooD p)) => Show (FooState' p)
deriving instance (Read (FooA p), Read (FooB p), Read (FooC p), Read (FooD p)) => Read (FooState' p)
withFoo' :: FooParams p => FooState' p > FooState' p
withFoo' = undefined
```
</details>
<details>
<summary>extra type synonym, slightly ugly API</summary>
```haskell
{# LANGUAGE TypeFamilies #}
{# LANGUAGE AllowAmbiguousTypes #}
class FooParams p where
type FooA p
type FooB p
type FooC p
type FooD p
 data decl still has 4 type params
data FooState a b c d = FooState
{ partA :: a
, partB :: b
, partC :: c
, partD :: d
}
deriving (Show, Read)
 apply the type family in a synonym, and expose this along with
 the constructor of the original data type if necessary.
 however, this gets ugly if the data structure is more complex
type FooState'' p = FooState (FooA p) (FooB p) (FooC p) (FooD p)
 API methods can use the type synonym to reduce the number of params
withFoo'' :: FooParams p => FooState'' p > FooState'' p
withFoo'' = undefined
```
</details>
## Proposal
I guess the error is a purposeful design choice to avoid surprising users  the same error occurs if e.g. using `IO p` instead of `FooA p`, and the same workarounds also work. Clearly, successfully and silently generating an instance with the context `(Show (IO p) .. ) =>`, would be surprising to users.
However for certain usecases such as the one I just described, this "potentiallysurprising" derived instance is in fact what we want, and is not surprising for these particular cases (e.g. think `Maybe p`). So it would be good if we could override the error and tell GHC to just use what it would have output. This could possibly be implemented as a new strategy with a name such as "stock_relaxed" or "stock_unchecked" or something.## Motivation
Consider this code:
```haskell
data FooState a b c d = FooState
{ partA :: a
, partB :: b
, partC :: c
, partD :: d
}
deriving (Show, Read)
withFoo :: FooState a b c d > FooState a b c d
withFoo = undefined
```
Eugh, the API has 4 type params. This is confusing for users, especially when they combine it with other functions that take additional type params. In fact (a, b, c, d) are logically "our" (as the author of `FooState`) type params, so we can simplify it like this, by grouping them together:
```haskell
{# LANGUAGE TypeFamilies #}
class FooParams p where
type FooA p
type FooB p
type FooC p
type FooD p
data FooState' p = FooState'
{ partA :: FooA p
, partB :: FooB p
, partC :: FooC p
, partD :: FooD p
}
 deriving (Show, Read)  fails!
withFoo' :: FooParams p => FooState' p > FooState' p
withFoo' = undefined
```
<details>
<summary>(Alternatively, using more advanced language features you can even avoid the typeclass context, although this prevents you defining class methods on FooA etc, click for details)
</summary>
```haskell
{# LANGUAGE TypeFamilies, RankNTypes, PolyKinds, DataKinds, StandaloneKindSignatures #}
data FooParams aT bT cT dT = FooParams
{ fooA :: aT
, fooB :: bT
, fooC :: cT
, fooD :: dT
}
type FooA :: forall a b c d. FooParams a b c d > *
type family FooA p where FooA ('FooParams a b c d) = a
type FooB :: forall a b c d. FooParams a b c d > *
type family FooB p where FooB ('FooParams a b c d) = b
type FooC :: forall a b c d. FooParams a b c d > *
type family FooC p where FooC ('FooParams a b c d) = c
type FooD :: forall a b c d. FooParams a b c d > *
type family FooD p where FooD ('FooParams a b c d) = d
data FooState' (p :: FooParams a b c d) = FooState'
{ partA :: FooA p
, partB :: FooB p
, partC :: FooC p
, partD :: FooD p
}
 deriving (Show, Read)  fails!
withFoo' :: FooState' p > FooState' p
withFoo' = undefined
```
</details>
Either way, great, our API now only has 1 type param.
Unfortunately, now `deriving (Show, Read)` fails (in both examples):
~~~~
Test.hs:26:13: error:
• No instance for (Show (FooA p))
arising from the first field of ‘FooState'’ (type ‘FooA p’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Show (FooState' p))

26  deriving (Show, Read)
 ^^^^
Test.hs:26:19: error:
• No instance for (Read (FooA p))
arising from the first field of ‘FooState'’ (type ‘FooA p’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Read (FooState' p))

26  deriving (Show, Read)
 ^^^^
~~~~
We can currently work around this in 2 ways, neither of which is ideal:
<details>
<summary>standalone deriving, tedious manual context</summary>
```haskell
{# LANGUAGE TypeFamilies #}
{# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #}
class FooParams p where
type FooA p
type FooB p
type FooC p
type FooD p
data FooState' p = FooState'
{ partA :: FooA p
, partB :: FooB p
, partC :: FooC p
, partD :: FooD p
}
 manually supply the context, eugh
 increases n*m with number of associated types, and the number of extra instances e.g. Eq, Ord
deriving instance (Show (FooA p), Show (FooB p), Show (FooC p), Show (FooD p)) => Show (FooState' p)
deriving instance (Read (FooA p), Read (FooB p), Read (FooC p), Read (FooD p)) => Read (FooState' p)
withFoo' :: FooParams p => FooState' p > FooState' p
withFoo' = undefined
```
</details>
<details>
<summary>extra type synonym, slightly ugly API</summary>
```haskell
{# LANGUAGE TypeFamilies #}
{# LANGUAGE AllowAmbiguousTypes #}
class FooParams p where
type FooA p
type FooB p
type FooC p
type FooD p
 data decl still has 4 type params
data FooState a b c d = FooState
{ partA :: a
, partB :: b
, partC :: c
, partD :: d
}
deriving (Show, Read)
 apply the type family in a synonym, and expose this along with
 the constructor of the original data type if necessary.
 however, this gets ugly if the data structure is more complex
type FooState'' p = FooState (FooA p) (FooB p) (FooC p) (FooD p)
 API methods can use the type synonym to reduce the number of params
withFoo'' :: FooParams p => FooState'' p > FooState'' p
withFoo'' = undefined
```
</details>
## Proposal
I guess the error is a purposeful design choice to avoid surprising users  the same error occurs if e.g. using `IO p` instead of `FooA p`, and the same workarounds also work. Clearly, successfully and silently generating an instance with the context `(Show (IO p) .. ) =>`, would be surprising to users.
However for certain usecases such as the one I just described, this "potentiallysurprising" derived instance is in fact what we want, and is not surprising for these particular cases (e.g. think `Maybe p`). So it would be good if we could override the error and tell GHC to just use what it would have output. This could possibly be implemented as a new strategy with a name such as "stock_relaxed" or "stock_unchecked" or something.https://gitlab.haskell.org/ghc/ghc//issues/17241Replace useages of con2tag_* in the deriving code with data2tag#20210209T20:13:52ZAndreas KlebingerReplace useages of con2tag_* in the deriving code with data2tag### Motivation
As I understand it we generate(ed?) con2tag_Con bindings in the deriving code well before data2Tag was a thing.
## Proposal
Now that we have data2Tag we should replace useages of con2tag with it.## Motivation
As I understand it we generate(ed?) con2tag_Con bindings in the deriving code well before data2Tag was a thing.
## Proposal
Now that we have data2Tag we should replace useages of con2tag with it.8.10.2https://gitlab.haskell.org/ghc/ghc//issues/9557Deriving instances is slow20210130T18:49:41ZFeuerbachDeriving instances is slowLet's take [this file](https://raw.githubusercontent.com/haskellsuite/haskellsrcexts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs) (from haskellsrcexts) and build it with O0. On my machine it takes 55s.
If we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.
Different classes vary in their compiletime cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.
haskellsrcexts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with O0 by default. It would be nice to get this fixed.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  7.8.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Deriving instances is slow","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Let's take [https://raw.githubusercontent.com/haskellsuite/haskellsrcexts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs this file] (from haskellsrcexts) and build it with O0. On my machine it takes 55s.\r\n\r\nIf we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.\r\n\r\nDifferent classes vary in their compiletime cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.\r\n\r\nhaskellsrcexts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with O0 by default. It would be nice to get this fixed.","type_of_failure":"OtherFailure","blocking":[]} >Let's take [this file](https://raw.githubusercontent.com/haskellsuite/haskellsrcexts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs) (from haskellsrcexts) and build it with O0. On my machine it takes 55s.
If we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.
Different classes vary in their compiletime cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.
haskellsrcexts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with O0 by default. It would be nice to get this fixed.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  7.8.3 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Deriving instances is slow","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Let's take [https://raw.githubusercontent.com/haskellsuite/haskellsrcexts/8e0153d33b66add96fd5606614ce7938d2029510/src/Language/Haskell/Exts/Annotated/Syntax.hs this file] (from haskellsrcexts) and build it with O0. On my machine it takes 55s.\r\n\r\nIf we remove deriving of all classes except Functor (which is the only one used by the module itself), the time will drop down to 4s.\r\n\r\nDifferent classes vary in their compiletime cost, but there's no single culprit. Among the costly ones are Generic, Data, Show, Ord.\r\n\r\nhaskellsrcexts users are very annoyed by its long compile time, about 10 minutes, especially because we don't compile with O0 by default. It would be nice to get this fixed.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/15376GHC determine illegal kind for standalone deriving with Deriving via20210123T17:56:02Zmizunashi_manaGHC determine illegal kind for standalone deriving with Deriving viaHappy to release GHC 8.6.1alpha1! I used it to test new extensions, and then I met below errors:
```
$ ghci8.6.0.20180627
GHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help
Prelude> :set XDerivingVia XStandaloneDeriving
Prelude> newtype FunctorWrapped f a = FunctorWrapped (f a)
Prelude> deriving via f instance Functor f => Functor (FunctorWrapped f)
<interactive>:3:33: error:
• Expected kind ‘* > *’, but ‘f’ has kind ‘*’
• In the first argument of ‘Functor’, namely ‘f’
In the standalone deriving instance for
‘Functor f => Functor (FunctorWrapped f)’
<interactive>:3:62: error:
• Expected kind ‘* > *’, but ‘f’ has kind ‘*’
• In the first argument of ‘FunctorWrapped’, namely ‘f’
In the first argument of ‘Functor’, namely ‘(FunctorWrapped f)’
In the standalone deriving instance for
‘Functor f => Functor (FunctorWrapped f)’
```
However,
```
newtype FunctorWrapped f a = FunctorWrapped (f a)
deriving Functor via f
```
is passed through on GHC 8.6.1alpha1.
Is this a bug or my misunderstand?
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"GHC determine illegal kind for standalone deriving with Deriving via","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Happy to release GHC 8.6.1alpha1! I used it to test new extensions, and then I met below errors:\r\n\r\n{{{\r\n$ ghci8.6.0.20180627\r\nGHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help\r\nPrelude> :set XDerivingVia XStandaloneDeriving\r\nPrelude> newtype FunctorWrapped f a = FunctorWrapped (f a)\r\nPrelude> deriving via f instance Functor f => Functor (FunctorWrapped f)\r\n\r\n<interactive>:3:33: error:\r\n • Expected kind ‘* > *’, but ‘f’ has kind ‘*’\r\n • In the first argument of ‘Functor’, namely ‘f’\r\n In the standalone deriving instance for\r\n ‘Functor f => Functor (FunctorWrapped f)’\r\n\r\n<interactive>:3:62: error:\r\n • Expected kind ‘* > *’, but ‘f’ has kind ‘*’\r\n • In the first argument of ‘FunctorWrapped’, namely ‘f’\r\n In the first argument of ‘Functor’, namely ‘(FunctorWrapped f)’\r\n In the standalone deriving instance for\r\n ‘Functor f => Functor (FunctorWrapped f)’\r\n}}}\r\n\r\nHowever,\r\n\r\n{{{\r\nnewtype FunctorWrapped f a = FunctorWrapped (f a)\r\n deriving Functor via f\r\n}}}\r\n\r\nis passed through on GHC 8.6.1alpha1.\r\n\r\nIs this a bug or my misunderstand?","type_of_failure":"OtherFailure","blocking":[]} >Happy to release GHC 8.6.1alpha1! I used it to test new extensions, and then I met below errors:
```
$ ghci8.6.0.20180627
GHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help
Prelude> :set XDerivingVia XStandaloneDeriving
Prelude> newtype FunctorWrapped f a = FunctorWrapped (f a)
Prelude> deriving via f instance Functor f => Functor (FunctorWrapped f)
<interactive>:3:33: error:
• Expected kind ‘* > *’, but ‘f’ has kind ‘*’
• In the first argument of ‘Functor’, namely ‘f’
In the standalone deriving instance for
‘Functor f => Functor (FunctorWrapped f)’
<interactive>:3:62: error:
• Expected kind ‘* > *’, but ‘f’ has kind ‘*’
• In the first argument of ‘FunctorWrapped’, namely ‘f’
In the first argument of ‘Functor’, namely ‘(FunctorWrapped f)’
In the standalone deriving instance for
‘Functor f => Functor (FunctorWrapped f)’
```
However,
```
newtype FunctorWrapped f a = FunctorWrapped (f a)
deriving Functor via f
```
is passed through on GHC 8.6.1alpha1.
Is this a bug or my misunderstand?
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"GHC determine illegal kind for standalone deriving with Deriving via","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Happy to release GHC 8.6.1alpha1! I used it to test new extensions, and then I met below errors:\r\n\r\n{{{\r\n$ ghci8.6.0.20180627\r\nGHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help\r\nPrelude> :set XDerivingVia XStandaloneDeriving\r\nPrelude> newtype FunctorWrapped f a = FunctorWrapped (f a)\r\nPrelude> deriving via f instance Functor f => Functor (FunctorWrapped f)\r\n\r\n<interactive>:3:33: error:\r\n • Expected kind ‘* > *’, but ‘f’ has kind ‘*’\r\n • In the first argument of ‘Functor’, namely ‘f’\r\n In the standalone deriving instance for\r\n ‘Functor f => Functor (FunctorWrapped f)’\r\n\r\n<interactive>:3:62: error:\r\n • Expected kind ‘* > *’, but ‘f’ has kind ‘*’\r\n • In the first argument of ‘FunctorWrapped’, namely ‘f’\r\n In the first argument of ‘Functor’, namely ‘(FunctorWrapped f)’\r\n In the standalone deriving instance for\r\n ‘Functor f => Functor (FunctorWrapped f)’\r\n}}}\r\n\r\nHowever,\r\n\r\n{{{\r\nnewtype FunctorWrapped f a = FunctorWrapped (f a)\r\n deriving Functor via f\r\n}}}\r\n\r\nis passed through on GHC 8.6.1alpha1.\r\n\r\nIs this a bug or my misunderstand?","type_of_failure":"OtherFailure","blocking":[]} >9.2.1https://gitlab.haskell.org/ghc/ghc//issues/15434DerivingVia (and perhaps even GND) works badly with DeriveGeneric20210123T01:13:40ZHiromi IshiiDerivingVia (and perhaps even GND) works badly with DeriveGeneric`DerivingVia` together with `DeriveGeneric` can generate wrong instances for `Generic`.
Consider the following:
```haskell
{# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia, GADTs #}
{# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies, UndecidableInstances #}
module Data.Foldable.Bad where
import GHC.Generics
newtype Bad a = Bad a deriving (Generic)
data Foo = Foo Int
deriving (Read, Show, Eq, Ord)
deriving (Generic) via Bad Foo
```
which gives the following representation, which is considered to be wrong for `Foo`:
```haskell
ghci> from $ Foo 12
M1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = Foo 12}}}}
ghci> :t it
it
:: D1
('MetaData "Bad" "Data.Foldable.Bad" "main" 'True)
(C1
('MetaCons "Bad" 'PrefixI 'False)
(S1
('MetaSel
'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)
(Rec0 Foo)))
x
```
Also, `DerivingStrategies` + GND + `DeriveGeneric` already can generate wrong instance:
```haskell
newtype Bad2 = Bad2 Bool
deriving newtype (Generic)
{
ghci> from $ Bad2 False
M1 {unM1 = L1 (M1 {unM1 = U1})}
ghci> :t it
it
:: D1
('MetaData "Bool" "GHC.Types" "ghcprim" 'False)
(C1 ('MetaCons "False" 'PrefixI 'False) U1
:+: C1 ('MetaCons "True" 'PrefixI 'False) U1)
x
}
```
I tested this against GHC 8.6.1alpha1.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"DerivingVia (and perhaps even GND) works badly with DeriveGeneric","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`DerivingVia` together with `DeriveGeneric` can generate wrong instances for `Generic`.\r\n\r\nConsider the following:\r\n\r\n{{{#!haskell\r\n{# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia, GADTs #}\r\n{# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies, UndecidableInstances #}\r\nmodule Data.Foldable.Bad where\r\nimport GHC.Generics\r\n\r\nnewtype Bad a = Bad a deriving (Generic)\r\ndata Foo = Foo Int\r\n deriving (Read, Show, Eq, Ord)\r\n deriving (Generic) via Bad Foo\r\n}}}\r\n\r\nwhich gives the following representation, which is considered to be wrong for `Foo`:\r\n\r\n{{{#!haskell\r\nghci> from $ Foo 12\r\nM1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = Foo 12}}}}\r\nghci> :t it\r\nit\r\n :: D1\r\n ('MetaData \"Bad\" \"Data.Foldable.Bad\" \"main\" 'True)\r\n (C1\r\n ('MetaCons \"Bad\" 'PrefixI 'False)\r\n (S1\r\n ('MetaSel\r\n 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)\r\n (Rec0 Foo)))\r\n x\r\n}}}\r\n\r\nAlso, `DerivingStrategies` + GND + `DeriveGeneric` already can generate wrong instance:\r\n\r\n{{{#!haskell\r\nnewtype Bad2 = Bad2 Bool\r\n deriving newtype (Generic)\r\n\r\n{\r\n\r\nghci> from $ Bad2 False\r\nM1 {unM1 = L1 (M1 {unM1 = U1})}\r\nghci> :t it\r\nit\r\n :: D1\r\n ('MetaData \"Bool\" \"GHC.Types\" \"ghcprim\" 'False)\r\n (C1 ('MetaCons \"False\" 'PrefixI 'False) U1\r\n :+: C1 ('MetaCons \"True\" 'PrefixI 'False) U1)\r\n x\r\n}\r\n\r\n}}}\r\n\r\nI tested this against GHC 8.6.1alpha1.","type_of_failure":"OtherFailure","blocking":[]} >`DerivingVia` together with `DeriveGeneric` can generate wrong instances for `Generic`.
Consider the following:
```haskell
{# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia, GADTs #}
{# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies, UndecidableInstances #}
module Data.Foldable.Bad where
import GHC.Generics
newtype Bad a = Bad a deriving (Generic)
data Foo = Foo Int
deriving (Read, Show, Eq, Ord)
deriving (Generic) via Bad Foo
```
which gives the following representation, which is considered to be wrong for `Foo`:
```haskell
ghci> from $ Foo 12
M1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = Foo 12}}}}
ghci> :t it
it
:: D1
('MetaData "Bad" "Data.Foldable.Bad" "main" 'True)
(C1
('MetaCons "Bad" 'PrefixI 'False)
(S1
('MetaSel
'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)
(Rec0 Foo)))
x
```
Also, `DerivingStrategies` + GND + `DeriveGeneric` already can generate wrong instance:
```haskell
newtype Bad2 = Bad2 Bool
deriving newtype (Generic)
{
ghci> from $ Bad2 False
M1 {unM1 = L1 (M1 {unM1 = U1})}
ghci> :t it
it
:: D1
('MetaData "Bool" "GHC.Types" "ghcprim" 'False)
(C1 ('MetaCons "False" 'PrefixI 'False) U1
:+: C1 ('MetaCons "True" 'PrefixI 'False) U1)
x
}
```
I tested this against GHC 8.6.1alpha1.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"DerivingVia (and perhaps even GND) works badly with DeriveGeneric","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`DerivingVia` together with `DeriveGeneric` can generate wrong instances for `Generic`.\r\n\r\nConsider the following:\r\n\r\n{{{#!haskell\r\n{# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia, GADTs #}\r\n{# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies, UndecidableInstances #}\r\nmodule Data.Foldable.Bad where\r\nimport GHC.Generics\r\n\r\nnewtype Bad a = Bad a deriving (Generic)\r\ndata Foo = Foo Int\r\n deriving (Read, Show, Eq, Ord)\r\n deriving (Generic) via Bad Foo\r\n}}}\r\n\r\nwhich gives the following representation, which is considered to be wrong for `Foo`:\r\n\r\n{{{#!haskell\r\nghci> from $ Foo 12\r\nM1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = Foo 12}}}}\r\nghci> :t it\r\nit\r\n :: D1\r\n ('MetaData \"Bad\" \"Data.Foldable.Bad\" \"main\" 'True)\r\n (C1\r\n ('MetaCons \"Bad\" 'PrefixI 'False)\r\n (S1\r\n ('MetaSel\r\n 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)\r\n (Rec0 Foo)))\r\n x\r\n}}}\r\n\r\nAlso, `DerivingStrategies` + GND + `DeriveGeneric` already can generate wrong instance:\r\n\r\n{{{#!haskell\r\nnewtype Bad2 = Bad2 Bool\r\n deriving newtype (Generic)\r\n\r\n{\r\n\r\nghci> from $ Bad2 False\r\nM1 {unM1 = L1 (M1 {unM1 = U1})}\r\nghci> :t it\r\nit\r\n :: D1\r\n ('MetaData \"Bool\" \"GHC.Types\" \"ghcprim\" 'False)\r\n (C1 ('MetaCons \"False\" 'PrefixI 'False) U1\r\n :+: C1 ('MetaCons \"True\" 'PrefixI 'False) U1)\r\n x\r\n}\r\n\r\n}}}\r\n\r\nI tested this against GHC 8.6.1alpha1.","type_of_failure":"OtherFailure","blocking":[]} >9.2.1https://gitlab.haskell.org/ghc/ghc//issues/18874Deriving multiple classes in standalone (or document this limitation)20201108T16:38:47ZJulien DebonDeriving multiple classes in standalone (or document this limitation)## Motivation
To the best of my knowledge (I could not find any information about it in the [GHC Standalone Deriving documentation](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#standalonederivingdeclarations)), it is not possible to derive multiple classes in a single standalone deriving declaration.
Repeating an identical deriving declaration only to change the derived instance seems like unnecessary boilerplate:
```haskell
deriving instance Eq (MyType 'Foo)
deriving instance Show (MyType 'Foo)
deriving instance Read (MyType 'Foo)
```
But this situation can actually become bugprone when used together with `via` strategy, as it becomes easy to have discrepancies. Example using [derivingaeson](https://hackage.haskell.org/package/derivingaeson) library:
```haskell
deriving via
( CustomJSON
'[ OmitNothingFields,
UnwrapUnaryRecords,
TagSingleConstructors,
FieldLabelModifier (StripPrefix "user", CamelToSnake)
]
)
instance
ToJSON (MyType 'Foo)
deriving via
( CustomJSON
'[ OmitNothingFields,  Oh, we forgot to add 'UnwrapUnaryRecords' here!
TagSingleConstructors,
FieldLabelModifier (StripPrefix "user", CamelToSnake)
]
)
instance
FromJSON (MyType 'Foo)
```
## Proposal
I propose GHC supports deriving several instances in a single standalone declaration.
I don't have a strong opinion on the syntax (nor have I put a lot of effort in thinking about it, I have to admit), though I give an example of what it could look like below:
```haskell
deriving instance (Eq, Show, Read) (MyType 'Foo)
deriving via
( CustomJSON
'[ OmitNothingFields,
UnwrapUnaryRecords,
TagSingleConstructors,
FieldLabelModifier (StripPrefix "user", CamelToSnake)
]
)
instance
(ToJSON, FromJSON) (MyType 'Foo)
```
Should this proposal get rejected, I think we should at least document this limitation.## Motivation
To the best of my knowledge (I could not find any information about it in the [GHC Standalone Deriving documentation](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#standalonederivingdeclarations)), it is not possible to derive multiple classes in a single standalone deriving declaration.
Repeating an identical deriving declaration only to change the derived instance seems like unnecessary boilerplate:
```haskell
deriving instance Eq (MyType 'Foo)
deriving instance Show (MyType 'Foo)
deriving instance Read (MyType 'Foo)
```
But this situation can actually become bugprone when used together with `via` strategy, as it becomes easy to have discrepancies. Example using [derivingaeson](https://hackage.haskell.org/package/derivingaeson) library:
```haskell
deriving via
( CustomJSON
'[ OmitNothingFields,
UnwrapUnaryRecords,
TagSingleConstructors,
FieldLabelModifier (StripPrefix "user", CamelToSnake)
]
)
instance
ToJSON (MyType 'Foo)
deriving via
( CustomJSON
'[ OmitNothingFields,  Oh, we forgot to add 'UnwrapUnaryRecords' here!
TagSingleConstructors,
FieldLabelModifier (StripPrefix "user", CamelToSnake)
]
)
instance
FromJSON (MyType 'Foo)
```
## Proposal
I propose GHC supports deriving several instances in a single standalone declaration.
I don't have a strong opinion on the syntax (nor have I put a lot of effort in thinking about it, I have to admit), though I give an example of what it could look like below:
```haskell
deriving instance (Eq, Show, Read) (MyType 'Foo)
deriving via
( CustomJSON
'[ OmitNothingFields,
UnwrapUnaryRecords,
TagSingleConstructors,
FieldLabelModifier (StripPrefix "user", CamelToSnake)
]
)
instance
(ToJSON, FromJSON) (MyType 'Foo)
```
Should this proposal get rejected, I think we should at least document this limitation.https://gitlab.haskell.org/ghc/ghc//issues/18213GND generates code that instantiates coerce too much20201031T21:03:41ZRyan ScottGND generates code that instantiates coerce too muchConsider this code from https://gitlab.haskell.org/ghc/ghc/issues/18148#note_270603:
```hs
{# LANGUAGE AllowAmbiguousTypes #}
{# LANGUAGE DataKinds #}
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE PolyKinds #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE StandaloneDeriving #}
module Bug where
class Foo a where
bar :: forall (x :: a). ()
bar = ()
instance Foo Int
newtype Quux a = Quux a
 deriving newtype instance _ => Foo (Quux Int)
deriving newtype instance Foo (Quux Int)
```
This typechecks in GHC 8.10.1. However, if you comment out the original `deriving newtype instance Foo (Quux Int)` line and uncomment the very similar line above it, it no longer typechecks:
```
Bug.hs:19:1: error:
• Couldn't match type ‘Int’ with ‘Quux Int’
arising from the coercion of the method ‘bar’
from type ‘forall (x :: Int). ()’
to type ‘forall (x :: Quux Int). ()’
• When deriving the instance for (Foo (Quux Int))

19  deriving newtype instance _ => Foo (Quux Int)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This is a strange inconsistency, given how similar these standalone `deriving` declarations are. Why does the original succeed but the line above it fail?
As it turns out, both of these really ought to fail, but the original only succeeds due to an unfortunate fluke in the way `GeneralizedNewtypeDeriving` works. Here is the code that the original declaration generates (with `ddumpderiv`):
```
==================== Derived instances ====================
Derived class instances:
instance Bug.Foo (Bug.Quux GHC.Types.Int) where
Bug.bar
= GHC.Prim.coerce @() @() (Bug.bar @GHC.Types.Int) ::
forall (x_aKF :: Bug.Quux GHC.Types.Int). ()
```
Notice that we are instantiating `coerce` with `@() @()`. But this is blatantly wrong—it really ought to be `coerce @(forall (x :: Int). ()) @(forall (x :: Quux Int). ())`, which the typechecker would reject (as it should). But GND generates `coerce @() @()` instead, and as a result, the use of `bar` on the RHS gets instantiated with `@Any`, which is not what was intended at all.
In contrast, the `deriving newtype instance _ => Foo (Quux Int)` line infers a `Coercible (forall (x :: Int). ()) (forall (x :: Quux Int). ())` constraint, which the constraint solver rejects (as it should). The original line does not use the same constraintinference machinery, so it bypasses this step.
What can be done about this? It's tempting to have the original declaration generate this code instead:
```hs
instance Foo (Quux Int) where
bar = coerce @(forall (x :: Int). ())
@(forall (x :: Quux Int). ())
bar
```
Sadly, doing so would break a number of test cases that involve quantified constraints in instance contexts, such as `T15290`. See [`Note [GND and QuantifiedConstraints]`](https://gitlab.haskell.org/ghc/ghc//blob/9afd92512b41cf6c6de3a17b474d8d4bb01158c3/compiler/GHC/Tc/Deriv/Generate.hs#L16861773) for the full story. In order to make these test cases succeed (as a part of the fix for #15290), we employed an [ugly hack](132273f34e394bf7e900d0c15e01e91edd711890) where we split the `forall`s off of any types used to instantiate `coerce` in GNDgenerated code. But, as the example above demonstrates, this hack creates just as many problems as it solves.
@simonpj believes that this hack (and all of `Note [GND and QuantifiedConstraints]`) could be avoided. I don't quite understand his grand vision, so I'll let him comment here about what his vision entails.
Another similar example of this bug arising can be found in #18148. However, that issue is ensnared in a separate discussion about the roles of arguments to type classes, as the examples in #18148 crucially involve `ConstrainedClassMethods`. The underlying bug in this issue, on the other hand, does not fundamentally involve `ConstrainedClassMethods` in any way, so @simonpj and I have decided to track it separately here.Consider this code from https://gitlab.haskell.org/ghc/ghc/issues/18148#note_270603:
```hs
{# LANGUAGE AllowAmbiguousTypes #}
{# LANGUAGE DataKinds #}
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE PolyKinds #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE StandaloneDeriving #}
module Bug where
class Foo a where
bar :: forall (x :: a). ()
bar = ()
instance Foo Int
newtype Quux a = Quux a
 deriving newtype instance _ => Foo (Quux Int)
deriving newtype instance Foo (Quux Int)
```
This typechecks in GHC 8.10.1. However, if you comment out the original `deriving newtype instance Foo (Quux Int)` line and uncomment the very similar line above it, it no longer typechecks:
```
Bug.hs:19:1: error:
• Couldn't match type ‘Int’ with ‘Quux Int’
arising from the coercion of the method ‘bar’
from type ‘forall (x :: Int). ()’
to type ‘forall (x :: Quux Int). ()’
• When deriving the instance for (Foo (Quux Int))

19  deriving newtype instance _ => Foo (Quux Int)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This is a strange inconsistency, given how similar these standalone `deriving` declarations are. Why does the original succeed but the line above it fail?
As it turns out, both of these really ought to fail, but the original only succeeds due to an unfortunate fluke in the way `GeneralizedNewtypeDeriving` works. Here is the code that the original declaration generates (with `ddumpderiv`):
```
==================== Derived instances ====================
Derived class instances:
instance Bug.Foo (Bug.Quux GHC.Types.Int) where
Bug.bar
= GHC.Prim.coerce @() @() (Bug.bar @GHC.Types.Int) ::
forall (x_aKF :: Bug.Quux GHC.Types.Int). ()
```
Notice that we are instantiating `coerce` with `@() @()`. But this is blatantly wrong—it really ought to be `coerce @(forall (x :: Int). ()) @(forall (x :: Quux Int). ())`, which the typechecker would reject (as it should). But GND generates `coerce @() @()` instead, and as a result, the use of `bar` on the RHS gets instantiated with `@Any`, which is not what was intended at all.
In contrast, the `deriving newtype instance _ => Foo (Quux Int)` line infers a `Coercible (forall (x :: Int). ()) (forall (x :: Quux Int). ())` constraint, which the constraint solver rejects (as it should). The original line does not use the same constraintinference machinery, so it bypasses this step.
What can be done about this? It's tempting to have the original declaration generate this code instead:
```hs
instance Foo (Quux Int) where
bar = coerce @(forall (x :: Int). ())
@(forall (x :: Quux Int). ())
bar
```
Sadly, doing so would break a number of test cases that involve quantified constraints in instance contexts, such as `T15290`. See [`Note [GND and QuantifiedConstraints]`](https://gitlab.haskell.org/ghc/ghc//blob/9afd92512b41cf6c6de3a17b474d8d4bb01158c3/compiler/GHC/Tc/Deriv/Generate.hs#L16861773) for the full story. In order to make these test cases succeed (as a part of the fix for #15290), we employed an [ugly hack](132273f34e394bf7e900d0c15e01e91edd711890) where we split the `forall`s off of any types used to instantiate `coerce` in GNDgenerated code. But, as the example above demonstrates, this hack creates just as many problems as it solves.
@simonpj believes that this hack (and all of `Note [GND and QuantifiedConstraints]`) could be avoided. I don't quite understand his grand vision, so I'll let him comment here about what his vision entails.
Another similar example of this bug arising can be found in #18148. However, that issue is ensnared in a separate discussion about the roles of arguments to type classes, as the examples in #18148 crucially involve `ConstrainedClassMethods`. The underlying bug in this issue, on the other hand, does not fundamentally involve `ConstrainedClassMethods` in any way, so @simonpj and I have decided to track it separately here.https://gitlab.haskell.org/ghc/ghc//issues/17328GeneralizedNewtypeDeriving should not require that constructor be in scope20200703T17:15:30ZRichard Eisenbergrae@richarde.devGeneralizedNewtypeDeriving should not require that constructor be in scopeAs I learned perusing !1916 (but you don't need to read that MR), `GeneralizedNewtypeDeriving` requires that the constructor of the newtype in question be in scope. Yet this isn't really necessary:
A.hs:
```hs
module A where
newtype N1 = MkN1 N2
newtype N2 = MkN2 N1
instance Eq N2 where
(==) = const (const False)
```
B.hs:
```hs
{# LANGUAGE DerivingStrategies, StandaloneDeriving, GeneralizedNewtypeDeriving,
DerivingVia #}
module B where
import A ( N1, N2(..) )
import Data.Coerce
 This fails:
 deriving newtype instance Eq N1
 This succeeds:
 deriving via N2 instance Eq N1
 This succeeds:
instance Eq N1 where
(==) = coerce ((==) :: N2 > N2 > Bool)
```
I would think that the three possible instance declarations in B.hs would all be completely equivalent. Yet the first is rejected while the last two are accepted.
This example is indeed silly, but it's possible to make mutuallyrecursive newtypes that are not silly (by using e.g. `Maybe` or `Either` to break the loop).
Conclusion: The `newtype` strategy should not require the newtype constructor to be in scope. Instead, it should rely on the `Coercible` machinery to trigger the usual case where we need the constructor in scope. Of course, we should make sure that the error message is sensible when this happens.As I learned perusing !1916 (but you don't need to read that MR), `GeneralizedNewtypeDeriving` requires that the constructor of the newtype in question be in scope. Yet this isn't really necessary:
A.hs:
```hs
module A where
newtype N1 = MkN1 N2
newtype N2 = MkN2 N1
instance Eq N2 where
(==) = const (const False)
```
B.hs:
```hs
{# LANGUAGE DerivingStrategies, StandaloneDeriving, GeneralizedNewtypeDeriving,
DerivingVia #}
module B where
import A ( N1, N2(..) )
import Data.Coerce
 This fails:
 deriving newtype instance Eq N1
 This succeeds:
 deriving via N2 instance Eq N1
 This succeeds:
instance Eq N1 where
(==) = coerce ((==) :: N2 > N2 > Bool)
```
I would think that the three possible instance declarations in B.hs would all be completely equivalent. Yet the first is rejected while the last two are accepted.
This example is indeed silly, but it's possible to make mutuallyrecursive newtypes that are not silly (by using e.g. `Maybe` or `Either` to break the loop).
Conclusion: The `newtype` strategy should not require the newtype constructor to be in scope. Instead, it should rely on the `Coercible` machinery to trigger the usual case where we need the constructor in scope. Of course, we should make sure that the error message is sensible when this happens.https://gitlab.haskell.org/ghc/ghc//issues/13731DeriveFunctor and friends don't understand type families20200608T17:11:37ZSophie TaylorDeriveFunctor and friends don't understand type families```hs
{# LANGUAGE DeriveFunctor #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GADTs #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE TypeFamilies #}
data Test ext a where
Foo :: a > Test ext a
Extend :: (ExtensionType ext a) > Test ext a
type family ExtensionType ext a
data ListExtension
type instance ExtensionType ListExtension a = [a]
deriving instance Functor (Test ListExtension)
{
a.hs:15:1: error:
• Can't make a derived instance of ‘Functor (Test ListExtension)’:
Constructor ‘Extend’ must use the type variable only as the last argument of a data type
• In the standalone deriving instance for
‘Functor (Test ListExtension)’

15  deriving instance Functor (Test ListExtension)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, modules loaded: none.
}
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1rc2 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"DeriveFunctor and friends don't understand type families","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1rc2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{# LANGUAGE DeriveFunctor #}\r\n{# LANGUAGE FlexibleInstances #}\r\n{# LANGUAGE GADTs #}\r\n{# LANGUAGE StandaloneDeriving #}\r\n{# LANGUAGE TypeFamilies #}\r\n\r\ndata Test ext a where\r\n Foo :: a > Test ext a\r\n Extend :: (ExtensionType ext a) > Test ext a\r\n\r\ntype family ExtensionType ext a\r\ndata ListExtension\r\ntype instance ExtensionType ListExtension a = [a]\r\n\r\nderiving instance Functor (Test ListExtension)\r\n\r\n{\r\n\r\na.hs:15:1: error:\r\n • Can't make a derived instance of ‘Functor (Test ListExtension)’:\r\n Constructor ‘Extend’ must use the type variable only as the last argument of a data type\r\n • In the standalone deriving instance for\r\n ‘Functor (Test ListExtension)’\r\n \r\n15  deriving instance Functor (Test ListExtension)\r\n  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\nFailed, modules loaded: none.\r\n}\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >```hs
{# LANGUAGE DeriveFunctor #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GADTs #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE TypeFamilies #}
data Test ext a where
Foo :: a > Test ext a
Extend :: (ExtensionType ext a) > Test ext a
type family ExtensionType ext a
data ListExtension
type instance ExtensionType ListExtension a = [a]
deriving instance Functor (Test ListExtension)
{
a.hs:15:1: error:
• Can't make a derived instance of ‘Functor (Test ListExtension)’:
Constructor ‘Extend’ must use the type variable only as the last argument of a data type
• In the standalone deriving instance for
‘Functor (Test ListExtension)’

15  deriving instance Functor (Test ListExtension)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, modules loaded: none.
}
```
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.2.1rc2 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"DeriveFunctor and friends don't understand type families","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1rc2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{# LANGUAGE DeriveFunctor #}\r\n{# LANGUAGE FlexibleInstances #}\r\n{# LANGUAGE GADTs #}\r\n{# LANGUAGE StandaloneDeriving #}\r\n{# LANGUAGE TypeFamilies #}\r\n\r\ndata Test ext a where\r\n Foo :: a > Test ext a\r\n Extend :: (ExtensionType ext a) > Test ext a\r\n\r\ntype family ExtensionType ext a\r\ndata ListExtension\r\ntype instance ExtensionType ListExtension a = [a]\r\n\r\nderiving instance Functor (Test ListExtension)\r\n\r\n{\r\n\r\na.hs:15:1: error:\r\n • Can't make a derived instance of ‘Functor (Test ListExtension)’:\r\n Constructor ‘Extend’ must use the type variable only as the last argument of a data type\r\n • In the standalone deriving instance for\r\n ‘Functor (Test ListExtension)’\r\n \r\n15  deriving instance Functor (Test ListExtension)\r\n  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\nFailed, modules loaded: none.\r\n}\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} >