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
> 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:
>>> 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.
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.
More information about the Glasgow-haskell-users