Illegal type synonym family application in instance (Was: Breakage with 6.10)

Manuel M T Chakravarty chak at cse.unsw.edu.au
Wed Oct 15 02:43:58 EDT 2008


Niklas Broberg:
> On 10/11/08, David Menendez <dave at zednenem.com> wrote:
>> On Fri, Oct 10, 2008 at 8:40 PM, Niklas Broberg
>> <niklas.broberg at gmail.com> wrote:
>>> src\HSX\XMLGenerator.hs:71:0
>>>   Illegal type synonym family application in instance: XML m
>>>   In the instance declaration for `EmbedAsChild m (XML m)´
>>> ---------------
>>>
>>> Could someone help me point out the problem here? The relevant  
>>> code is:
>>>
>>> instance XMLGen m => EmbedAsChild m (XML m) where
>>> asChild = return . return . xmlToChild
>>>
>>> class XMLGen m => EmbedAsChild m c where
>>> asChild :: c -> GenChildList m
>>>
>>> class Monad m => XMLGen m where
>>> type XML m
>>> ....
>>>
>>> This works fine with 6.8.3, so what's new in 6.10, and what would  
>>> I do
>>> to solve it?
>>
>>
>> I'm guessing there was a bug in 6.8.3 that allowed this. (The
>> implementation of type families is present but not supported in 6.8,
>> presumably because of problems like this.)
>>
>> I don't have 6.10, so I can't test anything, but you might try
>> rewriting the EmbedAsChild instances like so:
>>
>>    instance (XMLGen m, XML m ~ x) => EmbedAsChild m x where ...
>
> Thanks a lot David, that's indeed what I needed.
>
> I'm not sure I see why the style I used previously was illegal though,
> it seemed perfectly natural to me. And it works that way for
> `EmbedAsChild m (Child m)´, where `Child m´ is a data type family and
> not a synonym, so why not for a synonym too? But hey, as long as
> there's a way to do what I want. :-)

As suggested, it was a bug in 6.8.3 that you could make a class  
instance where the head involved a type synonym family.  We cannot  
allow synonym families in class instances heads as it is impossible to  
check for overlap of such instances; eg, consider

   type family F a
   type instance F Bool = Int

   class C a

   instance C Int
   instance C (F a)

Now a context (C (F Bool)) would match both instances.  This is  
especially bad, as the type instance for F Bool may be defined in a  
different module as the instances for C; so, it is even in principle  
impossible to check for such overlap.

The situation is different for data families as they are data types  
and not type synonyms.

Moreover,

   instance (XMLGen m, XML m ~ x) => EmbedAsChild m x where ...

is fine as it clearly overlaps with any other instance of EmbedAsChild.

I hope that clarifies the situation.

Manuel



More information about the Glasgow-haskell-users mailing list