Portability | non-portable |
---|---|
Stability | experimental |
Maintainer | Richard Eisenberg (eir@cis.upenn.edu) |
Safe Haskell | Trustworthy |
This module provides three class constraints that can be used to make roles stricter in your datatypes. Here is a typical use case:
-- Use an association list as a map: data Map k v = (Nominal k, Representational v) => MkMap [(k,v)]
With a declaration such as this, GHC will assign correct roles to k
and v
. In versions of GHC before roles, these constraints have no
effect. The constraints need be put on only one data constructor, though
there is no harm in duplicating them.
Note that these constraints can only make roles stricter, such as a
change from representational to nominal. Indeed, going the other way
would not be type-safe! Thus, there is no guarantee that a parameter
has the role given -- the guarantee is only that a parameter as
at least the role given. (Thus, Phantom
is always redundant and
is included only for completeness.)
Unfortunately, the trick above does not work for newtype
s, which
cannot accept constraints. The only solution there is Template Haskell.
Use the function roleAnnot
.
To check that the roles are what you would expect, see module Language.Haskell.RoleAnnots.Check.
Documentation
class Representational a Source
Mark a type parameter as having a representational role
Representational k a |
Mark a type parameter as having a phantom role. (This is always redundant.)
Phantom k a |
roleAnnot :: [Role] -> Q [Dec] -> Q [Dec]Source
A backward-compatible (almost) role annotation. To use, write code like this:
roleAnnot [NominalR, RepresentationalR] [d| newtype MyMap k v = MkMyMap [(k,v)] |]
You will, of course, need -XTemplateHaskell
.
The almost above refers to the fact that this will require the
-XRoleAnnotations
extension. How to avoid using CPP
in this case?
Put the extension in your .cabal file, like this:
if impl(ghc >= 7.8) default-extensions: RoleAnnotations
(Cabal files need no endif
-- they use indentation to detect the
body of the conditional.)
You can check this out in action in the
cabal file for no-role-annots (in the test-suite
section).