How can I combine two type constraints with a logical or in Haskell?
haskell, type-constraints, typeclass
Solution
I believe that there is no way to automatically pick an `ROr a b`; it would violate the open world assumption if, e.g. `b` was satisfied, but later `a` was satisfied as well; any conflict resolution rule would necessarily cause the addition of an instance to change the behaviour of existing code.
That is, picking `R` when `b` is satisfied but `a` is not breaks the open world assumption, because it involves deciding that an instance is not satisfied;1 even if you added a "both satisfied" constructor, you would be able to use it to decide whether an instance is not present (by seeing if you get an `L` or an `R`).
Therefore, I do not believe that such an or constraint is possible; if you can observe which instance you get, then you can create a program whose behaviour changes by adding an instance, and if you can't observe which instance you get, then it's pretty useless.
1 The difference between this and normal instance resolution, which can also fail, is that normally, the compiler cannot decide that a constraint is satisfied; here, you're asking the compiler to decide that the constraint cannot be satisfied. A subtle but important difference.
Problem
In Haskell we are given the ability to combine constraints on types with a logical and. Consider the following ``` type And (a :: Constraint) b = (a, b) ``` or more complicatedly ``` class (a, b) => And a b instance (a, b) => And a b ``` I want to know how to logically or two constraints together in Haskell. My closest attempt is this, but it doesn't quite work. In this attempt I reify type constraints with tags and than dereify them with implicit parameters. ``` data ROr a b where L :: a => ROr a b R :: b => ROr a b type Or a b = (?choose :: ROr a b) y :: Or (a ~ Integer) (Bool ~ Integer) => a y = case ?choose of L -> 4 x :: Integer x = let ?choose = L in y ``` It almost works, but the user has to apply the final part, and the compiler should do that for me. As well, this case does not let one choose a third choice when both constraints are satisfied. How can I logically or two constraints together?