Generalized Newtype Deriving not allowed in Safe Haskell

David Terei dave.terei at
Sun Apr 12 23:41:01 UTC 2015

On 12 April 2015 at 13:01, Richard Eisenberg <eir at> wrote:
> On Apr 12, 2015, at 9:51 AM, David Terei <dave.terei at> wrote:
>> 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.

A way to temper this as discussed in the ticket is to have the default
be determined by the export list. A data type with all it's
constructors exported can default to representational roles when
possible, while nominal roles would be the default when a subset of
constructors are exported.

This is more complex for users to understand, but does map to the
semantics expected under Haskell2010. It may be best to drive this
decision with data.

Luckily we've also got infrastructure for testing against Hackage:

> Richard
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at

More information about the ghc-devs mailing list