Surprising interaction between quantified constraints and constraint synonyms allows for synonym instances
Summary
This looks like it shouldn't compile, but it does:
{-# LANGUAGE ConstraintKinds, KindSignatures, QuantifiedConstraints, RankNTypes
, FlexibleContexts, MultiParamTypeClasses #-}
import Data.Kind
class SomeClass a
class OtherClass
type SomeClassUnit = OtherClass => SomeClass () :: Constraint
instance SomeClassUnit
The surprising part is AFAICT it behaves exactly as if the synonym definition was substituted into the instance declaration.
Removing the constraint in SomeClassUnit
yields the expected result:
• Illegal instance for a type synonym
A class instance must be for a class
• In the instance declaration for ‘SomeClassUnit’
One quirk that may or may not be relevant, if the type class in question has methods, those can't be defined in the synonym instance:
{-# LANGUAGE ConstraintKinds, KindSignatures, QuantifiedConstraints, RankNTypes
, FlexibleContexts, MultiParamTypeClasses #-}
import Data.Kind
class SomeClass a where
meth :: a
class OtherClass
type SomeClassUnit = OtherClass => SomeClass () :: Constraint
instance SomeClassUnit where
meth = ()
yields
‘meth’ is not a (visible) method of class ‘SomeClassUnit’
However, if those methods have default implementations, AFAICT that will work as if you just declared an empty instance.
Note that it also works with parameters:
{-# LANGUAGE ConstraintKinds, KindSignatures, QuantifiedConstraints, RankNTypes
, FlexibleContexts, MultiParamTypeClasses #-}
import Data.Kind
class SomeClass a
class OtherClass
type SomeClassSyn a = OtherClass => SomeClass a :: Constraint
instance SomeClassSyn ()
NB: instead of OtherClass
any constraint will do, e.g. () ~ ()
or something redundant like that. However, empty constraint tuple does not trigger this.
Steps to reproduce
Try to compile the code block above.
Expected behavior
• Illegal instance for a type synonym
A class instance must be for a class
• In the instance declaration for ‘SomeClassUnit’
Environment
- GHC version used: 8.10.7, 9.0.2, 9.2.4, 9.4.2
Optional:
- Operating System: gentoo linux
- System Architecture: x86_64