My completely off-the-cuff guess is that<br>    a a b b<br>isn&#39;t considered more or less specific than<br>    (x -&gt; a) ar (x -&gt; b) br<br>since they both apply some constraint on the types.  For example, it&#39;s not immediately clear that the first instance can&#39;t be used for (x -&gt; a) (x -&gt; a) (x -&gt; b) (x -&gt; b)<br>
<br>Whereas when you say<br>    a ar b br<br>the type<br>    (x -&gt; a) ar (x -&gt; b) br<br>is strictly more specific, so the overlapping instance can be chosen.<br><br>Remember instance selection is done entirely via the instance head, so<br>
    instance X a a<br>is not the same as<br>    instance (a ~ b) =&gt; X a b<br><br>The first case supplies an instance for any two equal types, and the second case supplies an instance for *any two types*, then throws an error if the compiler can&#39;t prove that the two types are equal.<br>
<br>For example, without overlapping instances, you can write<br><br>    class X a b where foo :: a -&gt; b<br><br>    instance X a a where foo = id<br>    instance X Int Bool where foo = (== 0)<br><br>But if instead you specify<br>
    instance (a ~ b) =&gt; X a b where foo = id<br>you can&#39;t specify the Int Bool instance without overlap.<br><br>  -- ryan<br><br><div class="gmail_quote">On Mon, Jul 30, 2012 at 12:32 PM, Artyom Kazak <span dir="ltr">&lt;<a href="mailto:artyom.kazak@gmail.com" target="_blank">artyom.kazak@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
I have accidentally written my version of polyvariadic composition combinator, `mcomp`. It differs from Oleg’s version ( <a href="http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-comp" target="_blank">http://okmij.org/ftp/Haskell/<u></u>polyvariadic.html#polyvar-comp</a> ) in three aspects: a) it is simpler, b) it works without enumerating basic cases (all existing types, in other words), and c) it needs more type extensions.<br>

<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
{-# LANGUAGE<br>
      MultiParamTypeClasses<br>
    , FunctionalDependencies<br>
    , FlexibleInstances<br>
    , UndecidableInstances<br>
    , TypeFamilies      , OverlappingInstances<br>
  #-}<br>
<br>
class Mcomp a ar b br | a br -&gt; b where<br>
  mcomp :: a -&gt; (ar -&gt; br) -&gt; b<br>
<br>
instance (a ~ ar, b ~ br) =&gt; Mcomp a ar b br where<br>
  mcomp a f = f a<br>
<br>
instance (Mcomp a ar b br) =&gt; Mcomp (x -&gt; a) ar (x -&gt; b) br where<br>
  mcomp a f = \x -&gt; mcomp (a x) f<br>
</blockquote>
<br>
My question is: why doesn’t it work when I replace<br>
<br>
    instance (a ~ ar, b ~ br) =&gt; Mcomp a ar b br<br>
<br>
with<br>
<br>
    instance Mcomp a a b b<br>
<br>
? I thought that equal letters mean equal types…<br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br>