My completely off-the-cuff guess is that<br> a a b b<br>isn't considered more or less specific than<br> (x -> a) ar (x -> b) br<br>since they both apply some constraint on the types. For example, it's not immediately clear that the first instance can't be used for (x -> a) (x -> a) (x -> b) (x -> b)<br>
<br>Whereas when you say<br> a ar b br<br>the type<br> (x -> a) ar (x -> 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) => 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'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 -> 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) => X a b where foo = id<br>you can'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"><<a href="mailto:artyom.kazak@gmail.com" target="_blank">artyom.kazak@gmail.com</a>></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 -> b where<br>
mcomp :: a -> (ar -> br) -> b<br>
<br>
instance (a ~ ar, b ~ br) => Mcomp a ar b br where<br>
mcomp a f = f a<br>
<br>
instance (Mcomp a ar b br) => Mcomp (x -> a) ar (x -> b) br where<br>
mcomp a f = \x -> 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) => 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>