So there are many advantages of having typeclasses in C a Bool form. Mostly because they let you do any logical operation between two constraints when the normal C a just implicitly ANDs everything.
If we consider ~ a class constraint, this can be done like so
class Equal x y b | x y -> b
instance Equal x x True
instance False ~ b => Equal x y b
But what makes this case special is the fact that putting x x in the head of the instance is equivalent to x ~ y => and then x y in the head. This is not the case for any other typeclass.
So if we try to do something similar for a class C we get something like
class C' x b | x -> b
instance C x => C' x True
instance False ~ Bool => C' x b
Unfortunately this doesn't work since only one of those instances will ever be picked because they don't discriminate on the type x so any type matches both heads.
I've also read https://www.haskell.org/haskellwiki/GHC/AdvancedOverlap which again doesn't apply for any class C because it requires you to rewrite all the instances of the original class. Ideally, I'd like my code to work with GHC.Exts.Constraint and KindSignatures so that C can be parametric.
So, for a class like this
class Match (c :: * -> Constraint) x b | c x -> b
How do I write the instances so that Match c x True if and only if c x, Match c x False otherwise?
C a Boolform is stronger thanC a. You are essentially asking how to collect the set of instances of a type class, which is impossible. - user2407038Match. In module A I definedata X = X, andclass A b x | b -> x; a :: Proxy b -> x; instance A True Int; instance A False Bool,test :: forall x b y . (Match Eq x b, A b y) => x -> y; test _ = a (Proxy :: Proxy b). I have module B (imports A), in which the type oftest Xmust beInt. In module C (import A) I haveinstance Eq Xsotest X :: Bool. Module D imports B and C. Module D can't can't force B and C to recompile, sotest Xmust paradoxically have two types at once. - user2407038Cto a value". - user2407038