From 4fe12f4cd9afa122a88fec88de8cea5f1d689a74 Mon Sep 17 00:00:00 2001 From: Richard Eisenberg Date: Tue, 22 Oct 2013 10:53:14 -0400 Subject: [PATCH] Update user manual with respect to new default for class roles. --- docs/users_guide/glasgow_exts.xml | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 57eb645..b475c36 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -3747,7 +3747,10 @@ where via this new mechanism. - The role of the last parameter of each of the ci is not nominal. (See .) + It is safe to coerce each of the methods of ci. That is, + the missing last argument to each of the ci is not used + at a nominal role in any of the ci's methods. + (See .) Then, for each ci, the derived instance declaration is: @@ -11148,18 +11151,26 @@ inference to determine the correct role for every parameter. It starts with a few base facts: (->) has two representational parameters; (~) has two nominal parameters; all type families' parameters are nominal; and all GADT-like parameters are nominal. Then, these -facts are propagated to all places where these types are used. By defaulting -parameters to role phnatom, any parameters unused in the right-hand side (or -used only in other types in phantom positions) will be phantom. Whenever a -parameter is used in a representational position (that is, used as a type -argument to a constructor whose corresponding variable is at role -representational), we raise its role from phantom to representational. +facts are propagated to all places where these types are used. The default +role for datatypes and synonyms is phantom; the default role for classes is +nominal. Thus, for datatypes and synonyms, any parameters unused in the +right-hand side (or used only in other types in phantom positions) will be +phantom. Whenever a parameter is used in a representational position (that is, +used as a type argument to a constructor whose corresponding variable is at +role representational), we raise its role from phantom to representational. Similarly, when a parameter is used in a nominal position, its role is upgraded to nominal. We never downgrade a role from nominal to phantom or representational, or from representational to phantom. In this way, we infer the most-general role for each parameter. + +Classes have their roles default to nominal to promote coherence of class +instances. If a C Int were stored in a datatype, it would +be quite bad if that were somehow changed into a C Age +somewhere, especially if another C Age had been declared! + + There is one particularly tricky case that should be explained: @@ -11234,6 +11245,9 @@ to be at role nominal. This would be done with a declaration type role Set nominal +Role annotations can also be used should a programmer wish to write +a class with a representational (or phantom) role. + The other place where role annotations may be necessary are in hs-boot files (), where the right-hand sides of definitions can be omitted. As usual, the @@ -11266,10 +11280,10 @@ Here are some examples: data T3 a b = MkT3 a -- OK: nominal is higher than necessary, but safe type role T4 nominal - data T4 a = MkT4 (a Int) -- OK, but N is higher than necessary + data T4 a = MkT4 (a Int) -- OK, but nominal is higher than necessary type role C representational _ - class C a b where ... -- OK + class C a b where ... -- OK, b will get a nominal role type role X nominal type X a = ... -- ERROR: role annotations not allowed for type synonyms -- 1.9.1