GHC issueshttps://gitlab.haskell.org/ghc/ghc//issues20210506T16:44:49Zhttps://gitlab.haskell.org/ghc/ghc//issues/19786DerivingVia is considered Safe20210506T16:44:49ZOleg 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/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/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/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/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/18219Relax inferred context simplification to allow "exotic" contexts for Generali...20200524T02:05:34ZAndrew PritchardRelax inferred context simplification to allow "exotic" contexts for GeneralizedNewtypeDeriving and DerivingVia instances.## Motivation
Many `GND` / `DerivingVia` instances that seem totally sensible must in practice be turned into `StandaloneDeriving` because their contexts cannot be inferred. However, `inferConstraintsCoerceBased` is already producing a sensible context for them, and all that's failing is simplifying that context. I suspect it's possible to simplify them differently from contexts coming from other deriving mechanisms, and make these deriving clauses work.
## Proposal
The following module defines a class and attempts to GND an instance of it, but fails because the inferred constraint simplifies to `C [a]`, which doesn't match any instance head.
```
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
module Example (Thing) where
class C a where method :: a > String
instance C [Bool] where method _ = ""
newtype Thing a = Thing [a] deriving newtype C
```
This happens because of the restriction described in the Note `[Exotic derived instance contexts]`. However, many uses of `DerivingVia` intuitively want to "just copy the context of the via instance". I'm having a hard time formalizing this intuition, since there can be odd situations like mutually recursive derived instances involving newtypes [1] or selfrecursive newtypes [2]. But a first pass is that if the `via` type is imported from another module and does not use the newtype itself as a type parameter, the system of equations being simplified for the GND instance can't be recursive, and it should suffice to simplify the context in isolation.
I tried horribly hacking up a GHC build to skip all simplification for GND and DerivingVia instances just to make sure it's only the simplification that's breaking the instance, and it sortof worked, in that it inferred a context that had unsimplified Coercible constraints but was otherwise reasonable:
```
b87b0c2c2947e1ccc983269180bfe604
$fCThing ::
(C [a],
([a] > GHC.Base.String) ~R# (Thing a > GHC.Base.String)) =>
C (Thing a)
DFunId
[]
```
These unsimplified Coercible constraints are a problem, though, since they break calling modules that don't import the relevant newtype constructors (and the stage2 GHC doesn't build). Of course this isn't meant to be a real implementation, just a way to prove to myself that `inferContextCoerceBased` was sufficient for these instances.
In general many of the new instances this enables would probably require `UndecidableInstances`, but I'm willing to enable that as necessary. Some more example modules affected by this:
A type family interfering with simplification:
```
{# LANGUAGE DataKinds #}
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE TypeApplications #}
{# LANGUAGE TypeFamilies #}
{# LANGUAGE UndecidableInstances #}
module Test where
import Data.Proxy (Proxy(..))
import GHC.TypeNats (Nat, KnownNat, natVal)
data SwarmOfNats = SwarmOfNats Nat Nat Nat
type family FstSwarm (x :: SwarmOfNats) :: Nat where
FstSwarm ('SwarmOfNats x y z) = x
class C a where method :: a > String
instance KnownNat n => C (Proxy n) where method _ = show (natVal @n Proxy)
 Fails simplifying because the context contains a type family application.
newtype Thing swarm = Thing (Proxy (FstSwarm swarm)) deriving newtype C
 deriving newtype instance KnownNat (FstSwarm swarm) => C (Thing swarm)
```
A `FlexibleContexts` constraint on a MPTC interfering with simplification:
```
{# LANGUAGE DeriveFoldable #}
{# LANGUAGE DerivingVia #}
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE MultiParamTypeClasses #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE UndecidableInstances #}
module Test where
 Disregard that this technique is blatantly overkill here...
data Rope str = Leaf str  Append (Rope str) (Rope str) deriving Foldable
class C str a where method :: a > Rope str
newtype WrappedC a = WrappedC { unWrappedC :: a }
instance C String a => Show (WrappedC a) where
showsPrec _p x s = foldr (++) s (method (unWrappedC x))
instance C [Char] a => C [Char] (Thing a) where
method Thing1 = Leaf "Thing1"
method (Thing2 x) = Append (Leaf "Thing2 ") (method x)
 Fails because the inferred context simplifies to `C [Char] a`.
data Thing a = Thing1  Thing2 a deriving Show via WrappedC (Thing a)
 deriving via WrappedC (Thing a) instance C [Char] a => Show (Thing a)
```
[1]: A GND instance that would give a recursive system:
```
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
module Test where
data Thing1 = Thing1 Thing2 Thing2 deriving Eq
newtype Thing2 = Thing2 Thing1 deriving newtype Eq
 Eq Thing1 = Eq Thing2 u Eq Thing2
 Eq Thing2 = Eq Thing1 u Coercible Thing2 Thing1
```
[2] A GND instance that would expand infinitely (but works because of the leastfixedpoint simplification):
```
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE ScopedTypeVariables #}
module Test where
data Proxy a = Proxy
class ShowType a where showType :: Proxy a > String
data Thing1 a
instance ShowType a => ShowType (Thing1 a) where
showType _ = "Thing1 " ++ showType (Proxy :: Proxy a)
newtype Weird a = Weird (Thing1 (Weird [a])) deriving newtype ShowType
 ShowType (Weird a) = ShowType (Thing1 (Weird [a]))
 = ShowType (Weird [a])
 = ShowType (Thing1 (Weird [[a]]))
 = ShowType (Weird [[a]])
 ...
```## Motivation
Many `GND` / `DerivingVia` instances that seem totally sensible must in practice be turned into `StandaloneDeriving` because their contexts cannot be inferred. However, `inferConstraintsCoerceBased` is already producing a sensible context for them, and all that's failing is simplifying that context. I suspect it's possible to simplify them differently from contexts coming from other deriving mechanisms, and make these deriving clauses work.
## Proposal
The following module defines a class and attempts to GND an instance of it, but fails because the inferred constraint simplifies to `C [a]`, which doesn't match any instance head.
```
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
module Example (Thing) where
class C a where method :: a > String
instance C [Bool] where method _ = ""
newtype Thing a = Thing [a] deriving newtype C
```
This happens because of the restriction described in the Note `[Exotic derived instance contexts]`. However, many uses of `DerivingVia` intuitively want to "just copy the context of the via instance". I'm having a hard time formalizing this intuition, since there can be odd situations like mutually recursive derived instances involving newtypes [1] or selfrecursive newtypes [2]. But a first pass is that if the `via` type is imported from another module and does not use the newtype itself as a type parameter, the system of equations being simplified for the GND instance can't be recursive, and it should suffice to simplify the context in isolation.
I tried horribly hacking up a GHC build to skip all simplification for GND and DerivingVia instances just to make sure it's only the simplification that's breaking the instance, and it sortof worked, in that it inferred a context that had unsimplified Coercible constraints but was otherwise reasonable:
```
b87b0c2c2947e1ccc983269180bfe604
$fCThing ::
(C [a],
([a] > GHC.Base.String) ~R# (Thing a > GHC.Base.String)) =>
C (Thing a)
DFunId
[]
```
These unsimplified Coercible constraints are a problem, though, since they break calling modules that don't import the relevant newtype constructors (and the stage2 GHC doesn't build). Of course this isn't meant to be a real implementation, just a way to prove to myself that `inferContextCoerceBased` was sufficient for these instances.
In general many of the new instances this enables would probably require `UndecidableInstances`, but I'm willing to enable that as necessary. Some more example modules affected by this:
A type family interfering with simplification:
```
{# LANGUAGE DataKinds #}
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE TypeApplications #}
{# LANGUAGE TypeFamilies #}
{# LANGUAGE UndecidableInstances #}
module Test where
import Data.Proxy (Proxy(..))
import GHC.TypeNats (Nat, KnownNat, natVal)
data SwarmOfNats = SwarmOfNats Nat Nat Nat
type family FstSwarm (x :: SwarmOfNats) :: Nat where
FstSwarm ('SwarmOfNats x y z) = x
class C a where method :: a > String
instance KnownNat n => C (Proxy n) where method _ = show (natVal @n Proxy)
 Fails simplifying because the context contains a type family application.
newtype Thing swarm = Thing (Proxy (FstSwarm swarm)) deriving newtype C
 deriving newtype instance KnownNat (FstSwarm swarm) => C (Thing swarm)
```
A `FlexibleContexts` constraint on a MPTC interfering with simplification:
```
{# LANGUAGE DeriveFoldable #}
{# LANGUAGE DerivingVia #}
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE MultiParamTypeClasses #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE UndecidableInstances #}
module Test where
 Disregard that this technique is blatantly overkill here...
data Rope str = Leaf str  Append (Rope str) (Rope str) deriving Foldable
class C str a where method :: a > Rope str
newtype WrappedC a = WrappedC { unWrappedC :: a }
instance C String a => Show (WrappedC a) where
showsPrec _p x s = foldr (++) s (method (unWrappedC x))
instance C [Char] a => C [Char] (Thing a) where
method Thing1 = Leaf "Thing1"
method (Thing2 x) = Append (Leaf "Thing2 ") (method x)
 Fails because the inferred context simplifies to `C [Char] a`.
data Thing a = Thing1  Thing2 a deriving Show via WrappedC (Thing a)
 deriving via WrappedC (Thing a) instance C [Char] a => Show (Thing a)
```
[1]: A GND instance that would give a recursive system:
```
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
module Test where
data Thing1 = Thing1 Thing2 Thing2 deriving Eq
newtype Thing2 = Thing2 Thing1 deriving newtype Eq
 Eq Thing1 = Eq Thing2 u Eq Thing2
 Eq Thing2 = Eq Thing1 u Coercible Thing2 Thing1
```
[2] A GND instance that would expand infinitely (but works because of the leastfixedpoint simplification):
```
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE ScopedTypeVariables #}
module Test where
data Proxy a = Proxy
class ShowType a where showType :: Proxy a > String
data Thing1 a
instance ShowType a => ShowType (Thing1 a) where
showType _ = "Thing1 " ++ showType (Proxy :: Proxy a)
newtype Weird a = Weird (Thing1 (Weird [a])) deriving newtype ShowType
 ShowType (Weird a) = ShowType (Thing1 (Weird [a]))
 = ShowType (Weird [a])
 = ShowType (Thing1 (Weird [[a]]))
 = ShowType (Weird [[a]])
 ...
```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/18148ConstrainedClassMethods can trigger unactionable redundant constraint warnin...20200522T23:35:24ZKoz RossConstrainedClassMethods can trigger unactionable redundant constraint warnings together with GND## Summary
If you use ``GeneralizedNewtypeDeriving`` (or indeed, ``DerivingVia``) to derive an instance of a type class whose methods have constraints that aren't in the type class head, it is possible to trigger redundant constraint warnings if the generated code would cause the constraints to be satisfied by whatever the type variables are set to. See the example given in 'steps to reproduce' for a demonstration. These warnings can't be actioned  the only option currently is to disable redundant constraint warnings completely.
## Steps to reproduce
Attempt to compile the following code with ``Wredundantconstraints`` enabled:
```haskell
{# LANGUAGE ConstrainedClassMethods #}
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE StandaloneDeriving #}
module Baz where
class Foo a where
bar :: (Num a) => a > a
bar = (+ 1)
instance Foo Int
newtype Quux a = Quux a
deriving newtype instance Foo (Quux Int)
```
This will emit a redundant constraint warning, as ``Int`` is already an instance of ``Num``.
## Expected behavior
Should compile, emitting no warnings.
## Environment
* GHC version used: 8.10.1
Optional:
* Operating System: GNU/Linux
* System Architecture: x86_64## Summary
If you use ``GeneralizedNewtypeDeriving`` (or indeed, ``DerivingVia``) to derive an instance of a type class whose methods have constraints that aren't in the type class head, it is possible to trigger redundant constraint warnings if the generated code would cause the constraints to be satisfied by whatever the type variables are set to. See the example given in 'steps to reproduce' for a demonstration. These warnings can't be actioned  the only option currently is to disable redundant constraint warnings completely.
## Steps to reproduce
Attempt to compile the following code with ``Wredundantconstraints`` enabled:
```haskell
{# LANGUAGE ConstrainedClassMethods #}
{# LANGUAGE DerivingStrategies #}
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE GeneralizedNewtypeDeriving #}
{# LANGUAGE StandaloneDeriving #}
module Baz where
class Foo a where
bar :: (Num a) => a > a
bar = (+ 1)
instance Foo Int
newtype Quux a = Quux a
deriving newtype instance Foo (Quux Int)
```
This will emit a redundant constraint warning, as ``Int`` is already an instance of ``Num``.
## Expected behavior
Should compile, emitting no warnings.
## Environment
* GHC version used: 8.10.1
Optional:
* Operating System: GNU/Linux
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc//issues/18101DeriveGeneric gets a wrong infix constructor associativity when type is decla...20200510T01:20:13ZXia LiyaoDeriveGeneric gets a wrong infix constructor associativity when type is declared in a different module## Summary
For example, the operators `(:)` (`NonEmpty`) and `(:)` (lists, `[]`) are `infixr 5`, but their `Generic.Rep` say otherwise (`'InfixI 'LeftAssociative 9`) (see code block below for an illustration).
My most plausible hypothesis for the cause is that `DeriveGeneric` does not take precedence into account when the type lives in a different module from its `Generic` instance. Indeed, `NonEmpty` and `[]` have their `Generic` instances derived in `GHC.Generic`, whereas things looks fine if we declare a type with an infix constructor and derive `Generic` in the same module.
```
ghci> :kind! (Rep [Int])
(Rep [Int]) :: * > *
= D1
('MetaData "[]" "GHC.Types" "ghcprim" 'False)
(C1 ('MetaCons "[]" 'PrefixI 'False) U1
:+: C1
('MetaCons ":" ('InfixI 'LeftAssociative 9) 'False)
...)
ghci> :kind! (Rep (NonEmpty Int))
(Rep (NonEmpty Int)) :: * > *
= D1
('MetaData "NonEmpty" "GHC.Base" "base" 'False)
(C1
('MetaCons ":" ('InfixI 'LeftAssociative 9) 'False)
...)
```
## Expected behavior
These two examples should read `'InfixI 'RightAssociative 5`.
## Environment
* GHC version used: 8.6, 8.8## Summary
For example, the operators `(:)` (`NonEmpty`) and `(:)` (lists, `[]`) are `infixr 5`, but their `Generic.Rep` say otherwise (`'InfixI 'LeftAssociative 9`) (see code block below for an illustration).
My most plausible hypothesis for the cause is that `DeriveGeneric` does not take precedence into account when the type lives in a different module from its `Generic` instance. Indeed, `NonEmpty` and `[]` have their `Generic` instances derived in `GHC.Generic`, whereas things looks fine if we declare a type with an infix constructor and derive `Generic` in the same module.
```
ghci> :kind! (Rep [Int])
(Rep [Int]) :: * > *
= D1
('MetaData "[]" "GHC.Types" "ghcprim" 'False)
(C1 ('MetaCons "[]" 'PrefixI 'False) U1
:+: C1
('MetaCons ":" ('InfixI 'LeftAssociative 9) 'False)
...)
ghci> :kind! (Rep (NonEmpty Int))
(Rep (NonEmpty Int)) :: * > *
= D1
('MetaData "NonEmpty" "GHC.Base" "base" 'False)
(C1
('MetaCons ":" ('InfixI 'LeftAssociative 9) 'False)
...)
```
## Expected behavior
These two examples should read `'InfixI 'RightAssociative 5`.
## Environment
* GHC version used: 8.6, 8.8https://gitlab.haskell.org/ghc/ghc//issues/17518Can't derive TYPE rep instances20191128T09:29:38ZIcelandjackCan't derive TYPE rep instances## Summary
Deriving fails when we have `TYPE rep`, not `Type`
```haskell
{# Language DerivingStrategies #}
{# Language GeneralizedNewtypeDeriving #}
{# Language KindSignatures #}
{# Language MagicHash #}
{# Language PolyKinds #}
{# Language UnliftedNewtypes #}
import GHC.Exts (TYPE, RuntimeRep(IntRep), Int#, (+#))
import Data.Coerce
class Num# (a# :: TYPE rep) where
add# :: a# > a# > a#
instance Num# Int# where
add# = (+#)
 • Cannot derive wellkinded instance of form ‘Num# (IdInt# ...)’
 Class ‘Num#’ expects an argument of kind ‘*’
 • In the newtype declaration for ‘IdInt#’
newtype IdInt# = IdInt# Int#
deriving
newtype Num#
```
deriving works for a levitypolymorphic `Id#`
```haskell
newtype Id# (a# :: TYPE rep) = Id# a#
deriving
newtype Num#
```
but sadly only for `@LiftedRep`
```
> :set fprintexplicitkinds
> :i Num#
..
instance Num# @'LiftedRep a# =>
Num# @'LiftedRep (Id# @'LiftedRep a#)
```
## Proposed improvements or changes
The first one should be derived at `TYPE IntRep`
```haskell
instance Num# (IdInt# :: TYPE IntRep) where
add# :: IdInt# > IdInt# > IdInt#
add# = coerce (add# @IntRep @Int#)
```
but the second one wouldn't work for all `rep`, how can we get it to work
```haskell
 Cannot use function with levitypolymorphic arguments:
 coerce :: (a# > a# > a#) > Id# a# > Id# a# > Id# a#
 Levitypolymorphic arguments:
 Id# a# :: TYPE rep
 Id# a# :: TYPE rep^[[0m^[[0m
instance Num# a# => Num# (Id# a# :: TYPE rep) where
add# :: Id# a# > Id# a# > Id# a#
add# = coerce (add# @rep @a#)
```
## Environment
* GHC version used: 8.10.0.20191123
## Summary
Deriving fails when we have `TYPE rep`, not `Type`
```haskell
{# Language DerivingStrategies #}
{# Language GeneralizedNewtypeDeriving #}
{# Language KindSignatures #}
{# Language MagicHash #}
{# Language PolyKinds #}
{# Language UnliftedNewtypes #}
import GHC.Exts (TYPE, RuntimeRep(IntRep), Int#, (+#))
import Data.Coerce
class Num# (a# :: TYPE rep) where
add# :: a# > a# > a#
instance Num# Int# where
add# = (+#)
 • Cannot derive wellkinded instance of form ‘Num# (IdInt# ...)’
 Class ‘Num#’ expects an argument of kind ‘*’
 • In the newtype declaration for ‘IdInt#’
newtype IdInt# = IdInt# Int#
deriving
newtype Num#
```
deriving works for a levitypolymorphic `Id#`
```haskell
newtype Id# (a# :: TYPE rep) = Id# a#
deriving
newtype Num#
```
but sadly only for `@LiftedRep`
```
> :set fprintexplicitkinds
> :i Num#
..
instance Num# @'LiftedRep a# =>
Num# @'LiftedRep (Id# @'LiftedRep a#)
```
## Proposed improvements or changes
The first one should be derived at `TYPE IntRep`
```haskell
instance Num# (IdInt# :: TYPE IntRep) where
add# :: IdInt# > IdInt# > IdInt#
add# = coerce (add# @IntRep @Int#)
```
but the second one wouldn't work for all `rep`, how can we get it to work
```haskell
 Cannot use function with levitypolymorphic arguments:
 coerce :: (a# > a# > a#) > Id# a# > Id# a# > Id# a#
 Levitypolymorphic arguments:
 Id# a# :: TYPE rep
 Id# a# :: TYPE rep^[[0m^[[0m
instance Num# a# => Num# (Id# a# :: TYPE rep) where
add# :: Id# a# > Id# a# > Id# a#
add# = coerce (add# @rep @a#)
```
## Environment
* GHC version used: 8.10.0.20191123
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/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/17183XDerivingVia (and deriving strategies) is under specified in the manual20190912T18:08:19ZRichard Eisenbergrae@richarde.devXDerivingVia (and deriving strategies) is under specified in the manualI had forgotten the syntax for derivingstrategies. Specifically, I wanted to know whether I had to put the strategy *before* or *after* the list of classes. So I looked it up.... but the [manual](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#derivingstrategies) doesn't say. The examples suggest that the strategy comes before, but then in the `XDerivingVia` section, the strategy comes after. Are both allowed? Is `via` allowed prefix? It is a mystery.
And then I looked through the `XDerivingVia` [documentation](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#derivingvia). That is explained entirely by example, with no standalone specification. Yet the specification really has been worked out  it's in the paper. This text should be incorporated into the users' guide, along with a link to the paper (which I also did not see). Also needed are a description of how typing works  or at least scoping. It's very nontrivial.I had forgotten the syntax for derivingstrategies. Specifically, I wanted to know whether I had to put the strategy *before* or *after* the list of classes. So I looked it up.... but the [manual](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#derivingstrategies) doesn't say. The examples suggest that the strategy comes before, but then in the `XDerivingVia` section, the strategy comes after. Are both allowed? Is `via` allowed prefix? It is a mystery.
And then I looked through the `XDerivingVia` [documentation](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#derivingvia). That is explained entirely by example, with no standalone specification. Yet the specification really has been worked out  it's in the paper. This text should be incorporated into the users' guide, along with a link to the paper (which I also did not see). Also needed are a description of how typing works  or at least scoping. It's very nontrivial.https://gitlab.haskell.org/ghc/ghc//issues/17037Stock deriving improvements20200123T19:42:31ZSophie TaylorStock deriving improvements## Motivation
Trying to use GHCderived code in performancesensitive applications leads to several problems:
1. SPECIALISE pragmas have nothing to inline if the relevant types with GHCderived instances are defined in another file
2. No class law RULES seem to be generated, either. This is particularly troublesome with DeriveFunctor/DeriveFoldable/DeriveTraversable.
## Proposal
1. GHCderived instances should have INLINABLE pragmas.
2. I'm pretty certain that GHC generates lawabiding instances for Functor/Foldable/Traversable, so the relevant laws should be generated as RULES specific for the types its generating instances for.## Motivation
Trying to use GHCderived code in performancesensitive applications leads to several problems:
1. SPECIALISE pragmas have nothing to inline if the relevant types with GHCderived instances are defined in another file
2. No class law RULES seem to be generated, either. This is particularly troublesome with DeriveFunctor/DeriveFoldable/DeriveTraversable.
## Proposal
1. GHCderived instances should have INLINABLE pragmas.
2. I'm pretty certain that GHC generates lawabiding instances for Functor/Foldable/Traversable, so the relevant laws should be generated as RULES specific for the types its generating instances for.https://gitlab.haskell.org/ghc/ghc//issues/17013GHC accepts DerivingViagenerated instances that violate functional dependencies20190801T11:47:52ZAlexis KingGHC accepts DerivingViagenerated instances that violate functional dependencies## Summary
Instances generated using `DerivingVia` are accepted even though equivalent handwritten instances are rejected due to violation of the (liberal) coverage condition.
## Steps to reproduce
This module demonstrates the problem:
```haskell
{# LANGUAGE DerivingVia #}
{# LANGUAGE FunctionalDependencies #}
{# LANGUAGE FlexibleInstances #}
module DerivingViaBug where
class C a b  b > a
newtype A t a = A a
instance C t (A t a)
data T = T
deriving (C a) via (A () T)
```
The above program is accepted. But if we write the `C a T` instance manually, rather than deriving it, the program is rejected:
```haskell
data T = T
instance C a T
```
```
src/DerivingViaBug.hs:13:10: error:
• Illegal instance declaration for ‘C a T’
The coverage condition fails in class ‘C’
for functional dependency: ‘b > a’
Reason: lhs type ‘T’ does not determine rhs type ‘a’
Undetermined variable: a
• In the instance declaration for ‘C a T’

13  instance C a T
 ^^^^^
```
## Expected behavior
The simplest solution to this problem would be to reject the derived instance. However, this introduces a bit of an inconsistency between functional dependencies and associated types. Consider the following similar program, which uses associated types instead of functional dependencies:
```haskell
{# LANGUAGE DerivingVia #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE TypeFamilies #}
{# LANGUAGE UndecidableInstances #}
module DerivingViaBug where
class C a where
type F a
newtype A t a = A a
instance C (A t a) where
type F (A t a) = t
data T = T
deriving (C) via (A () T)
```
This program is accepted, and the behavior is reasonable. The derived instance is
```haskell
instance C T where
type F T = F (A () T)
```
so `F T` is ultimately `()`. To achieve analogous behavior for functional dependencies, it seems like a reasonable derived instance could be
```haskell
instance C () T
```
which can be constructed by applying the substitution {`t` ↦ `()`, `a` ↦ `T`} to the original `C t (A t a)` instance declaration. I haven’t thought about it enough to say whether or not that would cause more problems than it would solve, however.
## Environment
* GHC version used: 8.6.5
* Operating System: macOS 10.14.5 (18F132)
* System Architecture: x86_64## Summary
Instances generated using `DerivingVia` are accepted even though equivalent handwritten instances are rejected due to violation of the (liberal) coverage condition.
## Steps to reproduce
This module demonstrates the problem:
```haskell
{# LANGUAGE DerivingVia #}
{# LANGUAGE FunctionalDependencies #}
{# LANGUAGE FlexibleInstances #}
module DerivingViaBug where
class C a b  b > a
newtype A t a = A a
instance C t (A t a)
data T = T
deriving (C a) via (A () T)
```
The above program is accepted. But if we write the `C a T` instance manually, rather than deriving it, the program is rejected:
```haskell
data T = T
instance C a T
```
```
src/DerivingViaBug.hs:13:10: error:
• Illegal instance declaration for ‘C a T’
The coverage condition fails in class ‘C’
for functional dependency: ‘b > a’
Reason: lhs type ‘T’ does not determine rhs type ‘a’
Undetermined variable: a
• In the instance declaration for ‘C a T’

13  instance C a T
 ^^^^^
```
## Expected behavior
The simplest solution to this problem would be to reject the derived instance. However, this introduces a bit of an inconsistency between functional dependencies and associated types. Consider the following similar program, which uses associated types instead of functional dependencies:
```haskell
{# LANGUAGE DerivingVia #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE TypeFamilies #}
{# LANGUAGE UndecidableInstances #}
module DerivingViaBug where
class C a where
type F a
newtype A t a = A a
instance C (A t a) where
type F (A t a) = t
data T = T
deriving (C) via (A () T)
```
This program is accepted, and the behavior is reasonable. The derived instance is
```haskell
instance C T where
type F T = F (A () T)
```
so `F T` is ultimately `()`. To achieve analogous behavior for functional dependencies, it seems like a reasonable derived instance could be
```haskell
instance C () T
```
which can be constructed by applying the substitution {`t` ↦ `()`, `a` ↦ `T`} to the original `C t (A t a)` instance declaration. I haven’t thought about it enough to say whether or not that would cause more problems than it would solve, however.
## Environment
* GHC version used: 8.6.5
* Operating System: macOS 10.14.5 (18F132)
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc//issues/15969Generic1 deriving should use more coercions20200123T19:38:55ZDavid FeuerGeneric1 deriving should use more coercionsConsider
```hs
newtype Foo a = Foo (Maybe [a]) deriving (Generic1)
```
This produces some rather unsatisfactory Core:
```
 to1 worker
Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a > Maybe [a]
Travv.$fGeneric1Foo1
= \ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) >
case ds_d9dZ `cast` <Co:103> of {
Nothing > GHC.Maybe.Nothing @ [a_a7RL];
Just a1_a9fD > GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)
}
 from1 worker
Travv.$fGeneric1Foo2 :: forall a. Foo a > Maybe (Rec1 [] a)
Travv.$fGeneric1Foo2
= \ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) >
case x_a7GJ `cast` <Co:2> of {
Nothing > GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);
Just a1_a9fD >
GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)
}
```
Both of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define
```hs
data Bar a = Bar (Maybe [a]) deriving Generic1
```
I get a `to1` worker that looks like
```
Travv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a > Bar a
Travv.$fGeneric1Bar_$cto1
= \ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) >
Travv.Bar
@ a_a7UA
(case ds_d9ho `cast` <Co:103> of {
Nothing > GHC.Maybe.Nothing @ [a_a7UA];
Just a1_a9iK > GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)
})
```
That `case` expression should really just be a cast.
I think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.6.2 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  RyanGlScott 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Generic1 deriving should use more coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["Generics"],"differentials":[],"test_case":"","architecture":"","cc":["RyanGlScott"],"type":"Bug","description":"Consider\r\n\r\n{{{#!hs\r\nnewtype Foo a = Foo (Maybe [a]) deriving (Generic1)\r\n}}}\r\n\r\nThis produces some rather unsatisfactory Core:\r\n\r\n{{{\r\n to1 worker\r\nTravv.$fGeneric1Foo1 :: forall a. Rep1 Foo a > Maybe [a]\r\nTravv.$fGeneric1Foo1\r\n = \\ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) >\r\n case ds_d9dZ `cast` <Co:103> of {\r\n Nothing > GHC.Maybe.Nothing @ [a_a7RL];\r\n Just a1_a9fD > GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)\r\n}\r\n\r\n from1 worker\r\nTravv.$fGeneric1Foo2 :: forall a. Foo a > Maybe (Rec1 [] a)\r\nTravv.$fGeneric1Foo2\r\n = \\ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) >\r\n case x_a7GJ `cast` <Co:2> of {\r\n Nothing > GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);\r\n Just a1_a9fD >\r\n GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)\r\n }\r\n}}}\r\n\r\nBoth of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define\r\n\r\n{{{#!hs\r\ndata Bar a = Bar (Maybe [a]) deriving Generic1\r\n}}}\r\n\r\nI get a `to1` worker that looks like\r\n\r\n{{{\r\nTravv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a > Bar a\r\nTravv.$fGeneric1Bar_$cto1\r\n = \\ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) >\r\n Travv.Bar\r\n @ a_a7UA\r\n (case ds_d9ho `cast` <Co:103> of {\r\n Nothing > GHC.Maybe.Nothing @ [a_a7UA];\r\n Just a1_a9iK > GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)\r\n })\r\n}}}\r\n\r\nThat `case` expression should really just be a cast.\r\n\r\nI think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.","type_of_failure":"OtherFailure","blocking":[]} >Consider
```hs
newtype Foo a = Foo (Maybe [a]) deriving (Generic1)
```
This produces some rather unsatisfactory Core:
```
 to1 worker
Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a > Maybe [a]
Travv.$fGeneric1Foo1
= \ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) >
case ds_d9dZ `cast` <Co:103> of {
Nothing > GHC.Maybe.Nothing @ [a_a7RL];
Just a1_a9fD > GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)
}
 from1 worker
Travv.$fGeneric1Foo2 :: forall a. Foo a > Maybe (Rec1 [] a)
Travv.$fGeneric1Foo2
= \ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) >
case x_a7GJ `cast` <Co:2> of {
Nothing > GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);
Just a1_a9fD >
GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)
}
```
Both of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define
```hs
data Bar a = Bar (Maybe [a]) deriving Generic1
```
I get a `to1` worker that looks like
```
Travv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a > Bar a
Travv.$fGeneric1Bar_$cto1
= \ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) >
Travv.Bar
@ a_a7UA
(case ds_d9ho `cast` <Co:103> of {
Nothing > GHC.Maybe.Nothing @ [a_a7UA];
Just a1_a9iK > GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)
})
```
That `case` expression should really just be a cast.
I think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.6.2 
 Type  Bug 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  RyanGlScott 
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Generic1 deriving should use more coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["Generics"],"differentials":[],"test_case":"","architecture":"","cc":["RyanGlScott"],"type":"Bug","description":"Consider\r\n\r\n{{{#!hs\r\nnewtype Foo a = Foo (Maybe [a]) deriving (Generic1)\r\n}}}\r\n\r\nThis produces some rather unsatisfactory Core:\r\n\r\n{{{\r\n to1 worker\r\nTravv.$fGeneric1Foo1 :: forall a. Rep1 Foo a > Maybe [a]\r\nTravv.$fGeneric1Foo1\r\n = \\ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) >\r\n case ds_d9dZ `cast` <Co:103> of {\r\n Nothing > GHC.Maybe.Nothing @ [a_a7RL];\r\n Just a1_a9fD > GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)\r\n}\r\n\r\n from1 worker\r\nTravv.$fGeneric1Foo2 :: forall a. Foo a > Maybe (Rec1 [] a)\r\nTravv.$fGeneric1Foo2\r\n = \\ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) >\r\n case x_a7GJ `cast` <Co:2> of {\r\n Nothing > GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);\r\n Just a1_a9fD >\r\n GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)\r\n }\r\n}}}\r\n\r\nBoth of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define\r\n\r\n{{{#!hs\r\ndata Bar a = Bar (Maybe [a]) deriving Generic1\r\n}}}\r\n\r\nI get a `to1` worker that looks like\r\n\r\n{{{\r\nTravv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a > Bar a\r\nTravv.$fGeneric1Bar_$cto1\r\n = \\ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) >\r\n Travv.Bar\r\n @ a_a7UA\r\n (case ds_d9ho `cast` <Co:103> of {\r\n Nothing > GHC.Maybe.Nothing @ [a_a7UA];\r\n Just a1_a9iK > GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)\r\n })\r\n}}}\r\n\r\nThat `case` expression should really just be a cast.\r\n\r\nI think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/15868Standard deriving should be less conservative when `UndecidableInstances` is ...20190722T17:04:42Zedsko@edsko.netStandard deriving should be less conservative when `UndecidableInstances` is enabledThe following program
```hs
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE TypeFamilies #}
{# LANGUAGE UndecidableInstances #}
module Exp where
type family F a
data T a = MkT (F a)
deriving instance Eq (F a) => Eq (T a)
data T2 a = T2 (T a)
deriving (Eq)
```
results in a type error
```
• No instance for (Eq (F a))
arising from the first field of ‘T2’ (type ‘T a’)
```
According the manual this is expected behaviour (https://downloads.haskell.org/\~ghc/latest/docs/html/users_guide/glasgow_exts.html\#inferredcontextforderivingclauses), but it is unfortunate; it seems to me that there is no deep reason that this instance should be rejected, other than an overly conservative check in the deriving machinery; I propose that this check is relaxed when the `UndecidableInstances` extension is enabled. Mind that I'm *not* proposing that it should also be able to infer the right constraints for `T` itself; but once I write such an explicit context myself once (for `T`), it seems to me that deriving the *same* constraints also for `T2` should be easy.
Note that right now we can workaround this problem using
```hs
class Eq (F a) => EqF a
deriving instance EqF a => Eq (T a)
data T2 a = T2 (T a)
deriving (Eq)
```
Normally however for such a class synonym we would then provide a single "authoritative" instance:
```hs
class Eq (F a) => EqF a
instance Eq (F a) => EqF a
```
but if we do that then we are back at the same error for `T2`, because ghc will go from the `EqF a` constraint to the `Eq (F a)` constraint, and then refuse to add that constraint.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.6.1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Standard deriving should be less conservative when `UndecidableInstances` is enabled","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The following program\r\n\r\n{{{#!hs\r\n{# LANGUAGE FlexibleContexts #}\r\n{# LANGUAGE FlexibleInstances #}\r\n{# LANGUAGE StandaloneDeriving #}\r\n{# LANGUAGE TypeFamilies #}\r\n{# LANGUAGE UndecidableInstances #}\r\n\r\nmodule Exp where\r\n\r\ntype family F a\r\n\r\ndata T a = MkT (F a)\r\n\r\nderiving instance Eq (F a) => Eq (T a)\r\n\r\ndata T2 a = T2 (T a)\r\n deriving (Eq)\r\n}}}\r\n\r\nresults in a type error\r\n\r\n{{{\r\n • No instance for (Eq (F a))\r\n arising from the first field of ‘T2’ (type ‘T a’)\r\n}}}\r\n\r\nAccording the manual this is expected behaviour (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#inferredcontextforderivingclauses), but it is unfortunate; it seems to me that there is no deep reason that this instance should be rejected, other than an overly conservative check in the deriving machinery; I propose that this check is relaxed when the `UndecidableInstances` extension is enabled. Mind that I'm ''not'' proposing that it should also be able to infer the right constraints for `T` itself; but once I write such an explicit context myself once (for `T`), it seems to me that deriving the ''same'' constraints also for `T2` should be easy.\r\n\r\nNote that right now we can workaround this problem using\r\n\r\n{{{#!hs\r\nclass Eq (F a) => EqF a\r\n\r\nderiving instance EqF a => Eq (T a)\r\n\r\ndata T2 a = T2 (T a)\r\n deriving (Eq)\r\n}}}\r\n\r\nNormally however for such a class synonym we would then provide a single \"authoritative\" instance:\r\n\r\n{{{#!hs\r\nclass Eq (F a) => EqF a\r\ninstance Eq (F a) => EqF a\r\n}}}\r\n\r\nbut if we do that then we are back at the same error for `T2`, because ghc will go from the `EqF a` constraint to the `Eq (F a)` constraint, and then refuse to add that constraint. ","type_of_failure":"OtherFailure","blocking":[]} >The following program
```hs
{# LANGUAGE FlexibleContexts #}
{# LANGUAGE FlexibleInstances #}
{# LANGUAGE StandaloneDeriving #}
{# LANGUAGE TypeFamilies #}
{# LANGUAGE UndecidableInstances #}
module Exp where
type family F a
data T a = MkT (F a)
deriving instance Eq (F a) => Eq (T a)
data T2 a = T2 (T a)
deriving (Eq)
```
results in a type error
```
• No instance for (Eq (F a))
arising from the first field of ‘T2’ (type ‘T a’)
```
According the manual this is expected behaviour (https://downloads.haskell.org/\~ghc/latest/docs/html/users_guide/glasgow_exts.html\#inferredcontextforderivingclauses), but it is unfortunate; it seems to me that there is no deep reason that this instance should be rejected, other than an overly conservative check in the deriving machinery; I propose that this check is relaxed when the `UndecidableInstances` extension is enabled. Mind that I'm *not* proposing that it should also be able to infer the right constraints for `T` itself; but once I write such an explicit context myself once (for `T`), it seems to me that deriving the *same* constraints also for `T2` should be easy.
Note that right now we can workaround this problem using
```hs
class Eq (F a) => EqF a
deriving instance EqF a => Eq (T a)
data T2 a = T2 (T a)
deriving (Eq)
```
Normally however for such a class synonym we would then provide a single "authoritative" instance:
```hs
class Eq (F a) => EqF a
instance Eq (F a) => EqF a
```
but if we do that then we are back at the same error for `T2`, because ghc will go from the `EqF a` constraint to the `Eq (F a)` constraint, and then refuse to add that constraint.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.6.1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Standard deriving should be less conservative when `UndecidableInstances` is enabled","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The following program\r\n\r\n{{{#!hs\r\n{# LANGUAGE FlexibleContexts #}\r\n{# LANGUAGE FlexibleInstances #}\r\n{# LANGUAGE StandaloneDeriving #}\r\n{# LANGUAGE TypeFamilies #}\r\n{# LANGUAGE UndecidableInstances #}\r\n\r\nmodule Exp where\r\n\r\ntype family F a\r\n\r\ndata T a = MkT (F a)\r\n\r\nderiving instance Eq (F a) => Eq (T a)\r\n\r\ndata T2 a = T2 (T a)\r\n deriving (Eq)\r\n}}}\r\n\r\nresults in a type error\r\n\r\n{{{\r\n • No instance for (Eq (F a))\r\n arising from the first field of ‘T2’ (type ‘T a’)\r\n}}}\r\n\r\nAccording the manual this is expected behaviour (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#inferredcontextforderivingclauses), but it is unfortunate; it seems to me that there is no deep reason that this instance should be rejected, other than an overly conservative check in the deriving machinery; I propose that this check is relaxed when the `UndecidableInstances` extension is enabled. Mind that I'm ''not'' proposing that it should also be able to infer the right constraints for `T` itself; but once I write such an explicit context myself once (for `T`), it seems to me that deriving the ''same'' constraints also for `T2` should be easy.\r\n\r\nNote that right now we can workaround this problem using\r\n\r\n{{{#!hs\r\nclass Eq (F a) => EqF a\r\n\r\nderiving instance EqF a => Eq (T a)\r\n\r\ndata T2 a = T2 (T a)\r\n deriving (Eq)\r\n}}}\r\n\r\nNormally however for such a class synonym we would then provide a single \"authoritative\" instance:\r\n\r\n{{{#!hs\r\nclass Eq (F a) => EqF a\r\ninstance Eq (F a) => EqF a\r\n}}}\r\n\r\nbut if we do that then we are back at the same error for `T2`, because ghc will go from the `EqF a` constraint to the `Eq (F a)` constraint, and then refuse to add that constraint. ","type_of_failure":"OtherFailure","blocking":[]} >https://gitlab.haskell.org/ghc/ghc//issues/15650Add (or document if already exist) ability to derive custom typeclasses via s...20190719T22:10:08ZDmitrii KovanikovAdd (or document if already exist) ability to derive custom typeclasses via source plugins## Problem
Suppose, I have some custom typeclass `Foo` defined in some library `foo`:
```hs
class Foo a where
... some methods ...
```
I would like to be able to derive instances of this typeclass for any possible data type using `deriving` clause just like GHC already does for typeclasses `Eq`, `Ord`, `Show`, `Read`, `Enum`, etc.:
```hs
data Bar = Bar  Baz
deriving (Eq, Ord, Foo)
```
There're already two possible ways to derive instances of custom typeclasses:
1. `anyclass` deriving strategy (usually involves `Generic`)
1. `XTemplateHaskell` solution.
But I would like to have sourcepluginbased solution for this problem so I can just add `fplugin=Foo.Plugin` and enjoy deriving capabilities.
## Advantage over existing approaches
Solution with `XTemplateHaskell` is not that pleasant to write and easy to maintain (you need to use libraries like http://hackage.haskell.org/package/thabstraction to support multiple GHC versions),involves scoping restriction and is syntactically uglier. Compare:
```hs
{# LANGUAGE TemplateHaskell #}
data Bar = Bar  Baz
deriving (Eq, Ord)
deriveFoo ''Bar
```
Solution with something like `Generic` introduces performance overhead (required for to/from generic representation conversion). This might not be significant for something like *parsing CLI arguments* but it's more important if you want to have efficient binary serialisation.
Also, it's known that deriving typeclasses is a relatively slow compilation process (https://github.com/tfausak/tfausak.github.io/issues/127) so there's slight chance that deriving typeclass manually can be slightly faster than deriving `Generic + MyClass`. Especially when maintainers of plugins can experiment with some caching strategies for deriving typeclasses.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.6.1beta1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Add (or document if already exist) ability to derive custom typeclasses via source plugins","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1beta1","keywords":["plugins,deriving,typeclass","source"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"== Problem\r\n\r\nSuppose, I have some custom typeclass `Foo` defined in some library `foo`:\r\n\r\n{{{#!hs\r\nclass Foo a where\r\n ... some methods ...\r\n}}}\r\n\r\nI would like to be able to derive instances of this typeclass for any possible data type using `deriving` clause just like GHC already does for typeclasses `Eq`, `Ord`, `Show`, `Read`, `Enum`, etc.:\r\n\r\n{{{#!hs\r\ndata Bar = Bar  Baz\r\n deriving (Eq, Ord, Foo)\r\n}}}\r\n\r\nThere're already two possible ways to derive instances of custom typeclasses:\r\n\r\n1. `anyclass` deriving strategy (usually involves `Generic`)\r\n2. `XTemplateHaskell` solution.\r\n\r\nBut I would like to have sourcepluginbased solution for this problem so I can just add `fplugin=Foo.Plugin` and enjoy deriving capabilities.\r\n\r\n== Advantage over existing approaches\r\n\r\nSolution with `XTemplateHaskell` is not that pleasant to write and easy to maintain (you need to use libraries like http://hackage.haskell.org/package/thabstraction to support multiple GHC versions),involves scoping restriction and is syntactically uglier. Compare:\r\n\r\n{{{#!hs\r\n{# LANGUAGE TemplateHaskell #}\r\n\r\ndata Bar = Bar  Baz\r\n deriving (Eq, Ord)\r\n\r\nderiveFoo ''Bar\r\n}}}\r\n\r\nSolution with something like `Generic` introduces performance overhead (required for to/from generic representation conversion). This might not be significant for something like ''parsing CLI arguments'' but it's more important if you want to have efficient binary serialisation. \r\n\r\nAlso, it's known that deriving typeclasses is a relatively slow compilation process (https://github.com/tfausak/tfausak.github.io/issues/127) so there's slight chance that deriving typeclass manually can be slightly faster than deriving `Generic + MyClass`. Especially when maintainers of plugins can experiment with some caching strategies for deriving typeclasses.","type_of_failure":"OtherFailure","blocking":[]} >## Problem
Suppose, I have some custom typeclass `Foo` defined in some library `foo`:
```hs
class Foo a where
... some methods ...
```
I would like to be able to derive instances of this typeclass for any possible data type using `deriving` clause just like GHC already does for typeclasses `Eq`, `Ord`, `Show`, `Read`, `Enum`, etc.:
```hs
data Bar = Bar  Baz
deriving (Eq, Ord, Foo)
```
There're already two possible ways to derive instances of custom typeclasses:
1. `anyclass` deriving strategy (usually involves `Generic`)
1. `XTemplateHaskell` solution.
But I would like to have sourcepluginbased solution for this problem so I can just add `fplugin=Foo.Plugin` and enjoy deriving capabilities.
## Advantage over existing approaches
Solution with `XTemplateHaskell` is not that pleasant to write and easy to maintain (you need to use libraries like http://hackage.haskell.org/package/thabstraction to support multiple GHC versions),involves scoping restriction and is syntactically uglier. Compare:
```hs
{# LANGUAGE TemplateHaskell #}
data Bar = Bar  Baz
deriving (Eq, Ord)
deriveFoo ''Bar
```
Solution with something like `Generic` introduces performance overhead (required for to/from generic representation conversion). This might not be significant for something like *parsing CLI arguments* but it's more important if you want to have efficient binary serialisation.
Also, it's known that deriving typeclasses is a relatively slow compilation process (https://github.com/tfausak/tfausak.github.io/issues/127) so there's slight chance that deriving typeclass manually can be slightly faster than deriving `Generic + MyClass`. Especially when maintainers of plugins can experiment with some caching strategies for deriving typeclasses.
<details><summary>Trac metadata</summary>
 Trac field  Value 
    
 Version  8.6.1beta1 
 Type  FeatureRequest 
 TypeOfFailure  OtherFailure 
 Priority  normal 
 Resolution  Unresolved 
 Component  Compiler 
 Test case  
 Differential revisions  
 BlockedBy  
 Related  
 Blocking  
 CC  
 Operating system  
 Architecture  
</details>
<! {"blocked_by":[],"summary":"Add (or document if already exist) ability to derive custom typeclasses via source plugins","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1beta1","keywords":["plugins,deriving,typeclass","source"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"== Problem\r\n\r\nSuppose, I have some custom typeclass `Foo` defined in some library `foo`:\r\n\r\n{{{#!hs\r\nclass Foo a where\r\n ... some methods ...\r\n}}}\r\n\r\nI would like to be able to derive instances of this typeclass for any possible data type using `deriving` clause just like GHC already does for typeclasses `Eq`, `Ord`, `Show`, `Read`, `Enum`, etc.:\r\n\r\n{{{#!hs\r\ndata Bar = Bar  Baz\r\n deriving (Eq, Ord, Foo)\r\n}}}\r\n\r\nThere're already two possible ways to derive instances of custom typeclasses:\r\n\r\n1. `anyclass` deriving strategy (usually involves `Generic`)\r\n2. `XTemplateHaskell` solution.\r\n\r\nBut I would like to have sourcepluginbased solution for this problem so I can just add `fplugin=Foo.Plugin` and enjoy deriving capabilities.\r\n\r\n== Advantage over existing approaches\r\n\r\nSolution with `XTemplateHaskell` is not that pleasant to write and easy to maintain (you need to use libraries like http://hackage.haskell.org/package/thabstraction to support multiple GHC versions),involves scoping restriction and is syntactically uglier. Compare:\r\n\r\n{{{#!hs\r\n{# LANGUAGE TemplateHaskell #}\r\n\r\ndata Bar = Bar  Baz\r\n deriving (Eq, Ord)\r\n\r\nderiveFoo ''Bar\r\n}}}\r\n\r\nSolution with something like `Generic` introduces performance overhead (required for to/from generic representation conversion). This might not be significant for something like ''parsing CLI arguments'' but it's more important if you want to have efficient binary serialisation. \r\n\r\nAlso, it's known that deriving typeclasses is a relatively slow compilation process (https://github.com/tfausak/tfausak.github.io/issues/127) so there's slight chance that deriving typeclass manually can be slightly faster than deriving `Generic + MyClass`. Especially when maintainers of plugins can experiment with some caching strategies for deriving typeclasses.","type_of_failure":"OtherFailure","blocking":[]} >8.6.1