Standard deriving should be less conservative when `UndecidableInstances` is enabled
The following program
{-# 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\#inferred-context-for-deriving-clauses), 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 work-around this problem using
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:
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.
Trac metadata
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 |