Again, sorry for the 11:59 meddling....

The syntax of role annotations is very heavy weight, and requires lots of CPP where there wasn't need before.  Two thoughts:

1) Couldn't we do something like use "cue" type constraints? For example, assuming the default is representational, and that phantom can just be inferred, all we need is a way to indicate nominal:
data (Nominal k) => Map k v = ...

This could then probably be easily made to compile in other compilers with some null library implementation of Nominal

2) An alternative to the above. We generally frown on constraints in a data / newtype declaration, but perhaps this is exactly the case for them, whereby we can now do away with the type role syntax: We can infer nominal if there are any constraints on a type parameter, representational if there are none, and phantom if there are no mentions in the right hand side:
data (Eq k) => Map k v = ...

This seems even nicer and just works with all compilers... but perhaps I'm missing something. (Yes, I imagine there are type constraints that shouldn't force nominal, but perhaps not worth worrying about?)


Mind you, this all just about syntax... the issue of what is the implication for libraries of the default being representational is still at hand.