<div dir="ltr"><div>You could write a type family like this one:<br><br>type family (x :: k) `IsOneOf` (y :: (k, k)) :: Bool where<br>  x `IsOneOf` '(x, _) = 'True<br>  x `IsOneOf` '(_, x) = 'True<br>  _ `IsOneOf` _ = 'False<br><br></div><div>This is a type family that checks if a given type matches at least one of a given pair of types.</div><div><br></div><div>Once you have that, you can easily add it as a constraint to your typeclass:<br><br>class c `IsOneOf` '(a, b) ~ 'True => Foo a b c | a b -> c where<br>  foo :: a -> b -> c</div><div><br></div><div>This seems to give you what you want: It means that no instance of your typeclass can be for types a, b, and c such that c that isn't equal to at least one of a or b.</div><div><br></div><div><div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jul 23, 2018 at 9:55 PM Olaf Klinke <<a href="mailto:olf@aatal-apotheke.de">olf@aatal-apotheke.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Dear cafe, <br>
<br>
today I wrote a type class with three parameters.<br>
<br>
class Foo a b c | a b -> c where<br>
  foo :: a -> b -> c<br>
instance Foo A R A where ...<br>
instance Foo R A A where ...<br>
<br>
In addition to the functional dependency I'd like to express that at least one of the parameters a and b is c, that is, Foo is the union of the two classes <br>
<br>
class Foo1 a b where<br>
  foo1 :: a -> b -> a<br>
class Foo2 a b where<br>
  foo2 :: a -> b -> b<br>
<br>
and furthermore the choice between Foo1 and Foo2 determines one parameter to be a fixed type, say R. I understand that logical disjunction poses problems for instance resolution [1] because adding an instance may affect the instance dictionary lookup. This should not happen in my case because in the end this would be a one-parameter type class. The ultimate aim is to use the same symbol for both a function<br>
foo :: R -> a -> a<br>
and for flip foo. Of course writing flip foo is not that much of a nuisance, I just wonder whether Haskell is expressive enough to do this. <br>
<br>
Olaf<br>
<br>
[1] <a href="https://stackoverflow.com/questions/10255148/how-can-i-combine-two-type-constraints-with-a-logical-or-in-haskell" rel="noreferrer" target="_blank">https://stackoverflow.com/questions/10255148/how-can-i-combine-two-type-constraints-with-a-logical-or-in-haskell</a><br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div></div></div></div>