
On Apr 12, 2015, at 9:51 AM, David Terei
Ideally I'd like to find a way forward that works for everyone and isn't just a Safe Haskell mode setting.
Agreed. I'm not convinced this can be done, but it's certainly worth trying.
I think the first question is, are there situations where you'd want to use `coerce` internally to a module but disallow it externally? The role mechanism is a little awkward as it doesn't allow this (although it does for newtype's). If yes, then I think we should start there.
Yes, the ability to use `coerce` within one module but not elsewhere would be nice. This can currently be simulated (without too much difficulty) with newtypes. A datatype D can have a more permissive role signature than an equivalent newtype N (where `newtype N = MkN D`). The package then exports N (without its constructor). This effectively allows local uses of `coerce`, even for datatypes. A more direct mechanism would be better, but I don't think we should bend over backwards for it.
If it seems we don't need external vs internal control, then we could simply change the default to be that GHC sets referential type parameters to nominal and allows them to be weakened to referential through role annotations. We could use hackage to test how much breakage this would cause.
I worry that the breakage would be significant. But, now that authors have had a chance to put in role annotations, maybe it wouldn't be so bad. The change to GHC to make this happen is trivial: just change default_role in TcTyDecls.initialRoleEnv1. I don't have the infrastructure around to make an all-of-Hackage test, but I'm happy to support someone else who does. Richard