<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body style='font-size: 10pt; font-family: Verdana,Geneva,sans-serif'>
<div><span>Hello Haskell-Cafe,</span></div>
<div><span> </span></div>
<div><span>I have a question regarding the rules on type class instances with the MultiParamTypeClasses extension.</span></div>
<div><span> </span></div>
<div>For single-parameter type classes, there is the restriction that an instance head must have the form `C (T a1 ... an)`, where `C` is a type class, `T` is a data type constructor and `a1 ... an` are distinct type variables ( <a href="https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/instances.html">https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/instances.html</a> ). To my knowledge, this restriction ensures the impossibility of potential overlap between instances (except for the case where two instance heads are equivalent, but this case is caught by an error message).</div>
<div><span> </span></div>
<div><span>This restriction can be lifted with the FlexibleInstances extension, so that instances like `instance C (a, a, b)` and `instance C (a, b, b)` are allowed. As can be seen in this example, FlexibleInstances introduces the potential of overlap with single-parameter type classes.</span></div>
<div><span> </span></div>
<div><span>When using MultiParamTypeClasses without FlexibleInstances, the current restrictions on instance heads are similiar to those for single-parameter classes. For each parameter, the instance type must have the form `(T a1 ... an)` with `a1 ... an` being distinct from one another, but type variables can be shared between instance types. Therefore, instances like `instance D [a] [a] [b]` and `instance D [a] [b] [b]` are allowed and do cause potential overlap. If there was the restriction of all type variables in the instance head being different from one another however, I think there would be no potential for overlap, just like with single-parameter type classes.</span></div>
<div><span> </span></div>
<div><span>To me, these instances allowed by MultiParamTypeClasses seem similar to the single-parameter class instances that are only possible with FlexibleInstances. And just like FlexibleInstances for single-parameter class instances, they introduce potential overlap, so that the MultiParamTypeClasses extension by itself becomes less "safe" than it otherwise would be. Therefore, it seems reasonable to me to only allow these repeated type variables in instance heads with the FlexibleInstances extension.</span></div>
<div><span> </span></div>
<div><span>So, is there a good reason for the design choice of allowing these kinds of overlap without FlexibleInstances? Am I missing something here? Or are the current rules the way they are because of historic reasons?</span></div>
<div><span> </span></div>
<div><span>Best regards,</span></div>
<div><span>Leif-Erik Krüger</span></div>

</body></html>