Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#8958 closed feature request (fixed)

Allow role inference on datatype contexts

Reported by: goldfire Owned by: goldfire
Priority: normal Milestone: 7.8.1
Component: Compiler Version: 7.8.1-rc2
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: roles/should_compile/T8958
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


Currently, role inference on a datatype examines the use of a type parameter in all constructors of that datatype. This, of course, includes any constraint contexts on these datatypes. But, the (stupid) datatype context is not consulted, as there is no need to do so for type safety.

However, by examining the datatype context, we can create a lightweight way of annotating roles, like this:

class Nominal a
instance Nominal a
type role Nominal nominal    -- this is redundant, but here for completeness

class Representational a
instance Representational a
type role Representational representational    -- this requires -XIncoherentInstances

class Phantom a                  -- any use of this class is redundant, but here for completeness
instance Phantom a
type role Phantom phantom

data (Nominal k, Representational v) => Map k v = ...

Because of the universal instances, these constraints never get in the way. This is admittedly an abuse of existing constructs, but it seems so useful that it's worth a little abuse.

Change History (8)

comment:1 Changed 3 years ago by Richard Eisenberg <eir@…>

In d468cd376ffc02cf9f4755275a316be914c482be/ghc:

Fix #8958.

We now do role inference on stupid datatype contexts, allowing a
lightweight role annotation syntax.

comment:2 Changed 3 years ago by goldfire

Milestone: 7.8.1
Status: newmerge
Test Case: roles/should_compile/T8958

This commit also fixed a latent bug in that the datatype context was not fully zonked in tcDataDefn.

Please merge if possible into 7.8.1 -- this tiny patch allows lightweight role annotations, all done in user space, as suggested by Mark Lentczner.

comment:3 Changed 3 years ago by thoughtpolice

Resolution: fixed
Status: mergeclosed

Merged, thanks!

comment:4 Changed 3 years ago by simonpj

Owner: goldfire deleted
Resolution: fixed
Status: closednew

I can see the motivation here, though it is a grievous hack.

But it needs documenting in the user manual!


comment:5 Changed 3 years ago by simonpj

Owner: set to goldfire

comment:6 Changed 3 years ago by goldfire

Resolution: fixed
Status: newclosed

The code in the original post is indeed a grievous hack, but the change in GHC in order to support it is not. Indeed, when Mark first suggested this approach, I thought it was too unprincipled to incorporate. However, the only change needed within GHC to support the idea in the original post is that role inference must look at datatype contexts. This is sensible, all on its own. In fact, the user manual, as originally written for role inference, needs no change: it states that role inference propagates role information from every place a type is used, which naturally includes a datatype context.

Now with this support in GHC, the grievous hack in my original post can be built in user-land. I have released it as a package no-role-annots. I don't really like it, but it seems to cause no harm and some might find it useful.

comment:7 Changed 3 years ago by simonpj

Fair enough. You are arguing that nothing belongs in the user manual because there is no special compiler behaviour.

Yet a user approaching roles might still miss all of this. We have a mechanism for this: a wike page at The "Documentation" link on GHC's home page gets you here. The "Collaborative documentation" section is for user-level documentation about how to use GHC, above and beyond the user manual. In particular there is user-level documentation for type system extensions. So that would be an excellent place for some user-facing documentation about roles, including a pointer to your library.

I'm not suggesting that it's your responsibility to write such a page; but starting one, with an invitation to others to add more, would be an excellent move.


comment:8 Changed 3 years ago by Simon Peyton Jones <simonpj@…>

In b4dd5667fe84cb6030d296e9e4563d4de62f718d/ghc:

Suppress uniques to stop output wobbling (test for Trac #8958)
Note: See TracTickets for help on using tickets.