the resulting binding is lazy like any other Haskell pattern binding. The
above example desugars like this:
<programlisting>
- f x = let t = case h x o f{ (# p,q #) -> (p,q)
+ f x = let t = case h x of { (# p,q #) -> (p,q) }
p = fst t
q = snd t
in ..body..
import <literal>GHC.Prim</literal> (see <xref linkend="primitives"/>);
the <option>-XMagicHash</option> extension
then allows you to <emphasis>refer</emphasis> to the <literal>Int#</literal>
- that is now in scope.</para>
+ that is now in scope. Note that with this option, the meaning of <literal>x#y = 0</literal>
+ is changed: it defines a function <literal>x#</literal> taking a single argument <literal>y</literal>;
+ to define the operator <literal>#</literal>, put a space: <literal>x # y = 0</literal>.
+
+</para>
<para> The <option>-XMagicHash</option> also enables some new forms of literals (see <xref linkend="glasgow-unboxed"/>):
<itemizedlist>
<listitem><para> <literal>'x'#</literal> has type <literal>Char#</literal></para> </listitem>
<listitem><para> <literal>"foo"#</literal> has type <literal>Addr#</literal></para> </listitem>
<listitem><para> <literal>3#</literal> has type <literal>Int#</literal>. In general,
any Haskell integer lexeme followed by a <literal>#</literal> is an <literal>Int#</literal> literal, e.g.
- <literal>-0x3A#</literal> as well as <literal>32#</literal></para>.</listitem>
+ <literal>-0x3A#</literal> as well as <literal>32#</literal>.</para></listitem>
<listitem><para> <literal>3##</literal> has type <literal>Word#</literal>. In general,
any non-negative Haskell integer lexeme followed by <literal>##</literal>
is a <literal>Word#</literal>. </para> </listitem>
</sect2>
<sect2 id="negative-literals">
- <title>Negative Literals</title>
+ <title>Negative literals</title>
<para>
The literal <literal>-123</literal> is, according to
Haskell98 and Haskell 2010, desugared as
<literal>negate (fromInteger 123)</literal>.
The language extension <option>-XNegativeLiterals</option>
means that it is instead desugared as
- <literal>fromInteger (-123)</literal>.
+ <literal>fromInteger (-123)</literal>.
</para>
<para>
<para>
Haskell 2010 and Haskell 98 define floating literals with
the syntax <literal>1.2e6</literal>. These literals have the
- type <literal>Fractional a => Fractional</literal>.
+ type <literal>Fractional a => a</literal>.
</para>
<para>
- The language extension <option>-XNumLiterals</option> allows
+ The language extension <option>-XNumDecimals</option> allows
you to also use the floating literal syntax for instances of
<literal>Integral</literal>, and have values like
<literal>(1.2e6 :: Num a => a)</literal>
<para>
View patterns are enabled by the flag <literal>-XViewPatterns</literal>.
More information and examples of view patterns can be found on the
-<ulink url="http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns">Wiki
+<ulink url="http://ghc.haskell.org/trac/ghc/wiki/ViewPatterns">Wiki
page</ulink>.
</para>
</programlisting>
(For some amplification on this design choice see
-<ulink url="http://hackage.haskell.org/trac/ghc/ticket/4061">Trac #4061</ulink>.)
+<ulink url="http://ghc.haskell.org/trac/ghc/ticket/4061">Trac #4061</ulink>.)
</para>
</listitem>
</sect2>
+ <!-- ===================== Pattern synonyms =================== -->
+
+<sect2 id="pattern-synonyms">
+<title>Pattern synonyms
+</title>
+
+<para>
+Pattern synonyms are enabled by the flag
+<literal>-XPatternSynonyms</literal>, which is required for both
+defining them <emphasis>and</emphasis> using them. More information
+and examples of view patterns can be found on the <ulink
+url="http://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms">Wiki
+page</ulink>.
+</para>
+
+<para>
+Pattern synonyms enable giving names to parametrized pattern
+schemes. They can also be thought of as abstract constructors that
+don't have a bearing on data representation. For example, in a
+programming language implementation, we might represent types of the
+language as follows:
+</para>
+
+<programlisting>
+data Type = App String [Type]
+</programlisting>
+
+<para>
+Here are some examples of using said representation.
+Consider a few types of the <literal>Type</literal> universe encoded
+like this:
+</para>
+
+<programlisting>
+ App "->" [t1, t2] -- t1 -> t2
+ App "Int" [] -- Int
+ App "Maybe" [App "Int" []] -- Maybe Int
+</programlisting>
+
+<para>
+This representation is very generic in that no types are given special
+treatment. However, some functions might need to handle some known
+types specially, for example the following two functions collect all
+argument types of (nested) arrow types, and recognize the
+<literal>Int</literal> type, respectively:
+</para>
+
+<programlisting>
+ collectArgs :: Type -> [Type]
+ collectArgs (App "->" [t1, t2]) = t1 : collectArgs t2
+ collectArgs _ = []
+
+ isInt :: Type -> Bool
+ isInt (App "Int" []) = True
+ isInt _ = False
+</programlisting>
+
+<para>
+Matching on <literal>App</literal> directly is both hard to read and
+error prone to write. And the situation is even worse when the
+matching is nested:
+</para>
+
+<programlisting>
+ isIntEndo :: Type -> Bool
+ isIntEndo (App "->" [App "Int" [], App "Int" []]) = True
+ isIntEndo _ = False
+</programlisting>
+
+<para>
+Pattern synonyms permit abstracting from the representation to expose
+matchers that behave in a constructor-like manner with respect to
+pattern matching. We can create pattern synonyms for the known types
+we care about, without committing the representation to them (note
+that these don't have to be defined in the same module as the
+<literal>Type</literal> type):
+</para>
+
+<programlisting>
+ pattern Arrow t1 t2 = App "->" [t1, t2]
+ pattern Int = App "Int" []
+ pattern Maybe t = App "Maybe" [t]
+</programlisting>
+
+<para>
+Which enables us to rewrite our functions in a much cleaner style:
+</para>
+
+<programlisting>
+ collectArgs :: Type -> [Type]
+ collectArgs (Arrow t1 t2) = t1 : collectArgs t2
+ collectArgs _ = []
+
+ isInt :: Type -> Bool
+ isInt Int = True
+ isInt _ = False
+
+ isIntEndo :: Type -> Bool
+ isIntEndo (Arrow Int Int) = True
+ isIntEndo _ = False
+</programlisting>
+
+<para>
+ Note that in this example, the pattern synonyms
+ <literal>Int</literal> and <literal>Arrow</literal> can also be used
+ as expressions (they are <emphasis>bidirectional</emphasis>). This
+ is not necessarily the case: <emphasis>unidirectional</emphasis>
+ pattern synonyms can also be declared with the following syntax:
+</para>
+
+<programlisting>
+ pattern Head x <- x:xs
+</programlisting>
+
+<para>
+In this case, <literal>Head</literal> <replaceable>x</replaceable>
+cannot be used in expressions, only patterns, since it wouldn't
+specify a value for the <replaceable>xs</replaceable> on the
+right-hand side.
+</para>
+
+<para>
+The semantics of a unidirectional pattern synonym declaration and
+usage are as follows:
+
+<itemizedlist>
+
+<listitem> Syntax:
+<para>
+A pattern synonym declaration can be either unidirectional or
+bidirectional. The syntax for unidirectional pattern synonyms is:
+</para>
+<programlisting>
+ pattern Name args <- pat
+</programlisting>
+<para>
+ and the syntax for bidirectional pattern synonyms is:
+</para>
+<programlisting>
+ pattern Name args = pat
+</programlisting>
+<para>
+ Pattern synonym declarations can only occur in the top level of a
+ module. In particular, they are not allowed as local
+ definitions. Currently, they also don't work in GHCi, but that is a
+ technical restriction that will be lifted in later versions.
+</para>
+<para>
+ The name of the pattern synonym itself is in the same namespace as
+ proper data constructors. Either prefix or infix syntax can be
+ used. In export/import specifications, you have to prefix pattern
+ names with the <literal>pattern</literal> keyword, e.g.:
+</para>
+<programlisting>
+ module Example (pattern Single) where
+ pattern Single x = [x]
+</programlisting>
+</listitem>
+
+<listitem> Scoping:
+
+<para>
+ The variables in the left-hand side of the definition are bound by
+ the pattern on the right-hand side. For bidirectional pattern
+ synonyms, all the variables of the right-hand side must also occur
+ on the left-hand side; also, wildcard patterns and view patterns are
+ not allowed. For unidirectional pattern synonyms, there is no
+ restriction on the right-hand side pattern.
+</para>
+
+<para>
+ Pattern synonyms cannot be defined recursively.
+</para>
+
+</listitem>
+
+<listitem> Typing:
+
+<para>
+ Given a pattern synonym definition of the form
+</para>
+<programlisting>
+ pattern P var1 var2 ... varN <- pat
+</programlisting>
+<para>
+ it is assigned a <emphasis>pattern type</emphasis> of the form
+</para>
+<programlisting>
+ pattern CProv => P t1 t2 ... tN :: CReq => t
+</programlisting>
+<para>
+ where <replaceable>CProv</replaceable> and
+ <replaceable>CReq</replaceable> are type contexts, and
+ <replaceable>t1</replaceable>, <replaceable>t2</replaceable>, ...,
+ <replaceable>tN</replaceable> and <replaceable>t</replaceable> are
+ types.
+</para>
+
+<para>
+A pattern synonym of this type can be used in a pattern if the
+instatiated (monomorphic) type satisfies the constraints of
+<replaceable>CReq</replaceable>. In this case, it extends the context
+available in the right-hand side of the match with
+<replaceable>CProv</replaceable>, just like how an existentially-typed
+data constructor can extend the context.
+</para>
+
+<para>
+For example, in the following program:
+</para>
+<programlisting>
+{-# LANGUAGE PatternSynonyms, GADTs #-}
+module ShouldCompile where
+
+data T a where
+ MkT :: (Show b) => a -> b -> T a
+
+pattern ExNumPat x = MkT 42 x
+</programlisting>
+
+<para>
+the pattern type of <literal>ExNumPat</literal> is
+</para>
+
+<programlisting>
+pattern (Show b) => ExNumPat b :: (Num a, Eq a) => T a
+</programlisting>
+
+<para>
+ and so can be used in a function definition like the following:
+</para>
+
+<programlisting>
+ f :: (Num t, Eq t) => T t -> String
+ f (ExNumPat x) = show x
+</programlisting>
+
+<para>
+ For bidirectional pattern synonyms, uses as expressions have the type
+</para>
+<programlisting>
+ (CProv, CReq) => t1 -> t2 -> ... -> tN -> t
+</programlisting>
+
+<para>
+ So in the previous example, <literal>ExNumPat</literal>,
+ when used in an expression, has type
+</para>
+<programlisting>
+ ExNumPat :: (Show b, Num a, Eq a) => b -> T t
+</programlisting>
+
+</listitem>
+
+<listitem> Matching:
+
+<para>
+A pattern synonym occurrence in a pattern is evaluated by first
+matching against the pattern synonym itself, and then on the argument
+patterns. For example, in the following program, <literal>f</literal>
+and <literal>f'</literal> are equivalent:
+</para>
+
+<programlisting>
+pattern Pair x y <- [x, y]
+
+f (Pair True True) = True
+f _ = False
+
+f' [x, y] | True <- x, True <- y = True
+f' _ = False
+</programlisting>
+
+<para>
+ Note that the strictness of <literal>f</literal> differs from that
+ of <literal>g</literal> defined below:
+</para>
+
+<programlisting>
+g [True, True] = True
+g _ = False
+
+*Main> f (False:undefined)
+*** Exception: Prelude.undefined
+*Main> g (False:undefined)
+False
+</programlisting>
+</listitem>
+</itemizedlist>
+</para>
+
+</sect2>
+
<!-- ===================== n+k patterns =================== -->
<sect2 id="n-k-patterns">
f x = case x of { }
</programlisting>
With dependently-typed features it is more useful
-(see <ulink url="http://hackage.haskell.org/trac/ghc/ticket/2431">Trac</ulink>).
+(see <ulink url="http://ghc.haskell.org/trac/ghc/ticket/2431">Trac</ulink>).
For example, consider these two candidate definitions of <literal>absurd</literal>:
<programlisting>
data a :==: b where
We much prefer (B). Why? Because GHC can figure out that <literal>(True :~: False)</literal>
is an empty type. So (B) has no partiality and GHC should be able to compile with
<option>-fwarn-incomplete-patterns</option>. (Though the pattern match checking is not
-yet clever enough to do that.
+yet clever enough to do that.)
On the other hand (A) looks dangerous, and GHC doesn't check to make
sure that, in fact, the function can never get called.
</para>
...
_ | guardN -> exprN
</programlisting>
-except that multi-way if-expressions do not alter the layout.
+</para>
+
+<para>Multi-way if expressions introduce a new layout context. So the
+example above is equivalent to:
+<programlisting>
+ if { | guard1 -> expr1
+ ; | ...
+ ; | guardN -> exprN
+ }
+</programlisting>
+The following behaves as expected:
+<programlisting>
+ if | guard1 -> if | guard2 -> expr2
+ | guard3 -> expr3
+ | guard4 -> expr4
+</programlisting>
+because layout translates it as
+<programlisting>
+ if { | guard1 -> if { | guard2 -> expr2
+ ; | guard3 -> expr3
+ }
+ ; | guard4 -> expr4
+ }
+</programlisting>
+Layout with multi-way if works in the same way as other layout
+contexts, except that the semi-colons between guards in a multi-way if
+are optional. So it is not necessary to line up all the guards at the
+same column; this is consistent with the way guards work in function
+definitions and case expressions.
</para>
</sect2>
<varlistentry>
<term>
- <literal>?<replaceable>varid</replaceable></literal>,
- <literal>%<replaceable>varid</replaceable></literal>
+ <literal>?<replaceable>varid</replaceable></literal>
<indexterm><primary>implicit parameters</primary></indexterm>
</term>
<listitem><para>
<literal>[e|</literal>, <literal>[p|</literal>,
<literal>[d|</literal>, <literal>[t|</literal>,
<literal>$(</literal>,
- <literal>$<replaceable>varid</replaceable></literal>
+ <literal>$$(</literal>,
+ <literal>[||</literal>,
+ <literal>[e||</literal>,
+ <literal>$<replaceable>varid</replaceable></literal>,
+ <literal>$$<replaceable>varid</replaceable></literal>
<indexterm><primary>Template Haskell</primary></indexterm>
</term>
<listitem><para>
<varlistentry>
<term>
- <literal>[:<replaceable>varid</replaceable>|</literal>
+ <literal>[<replaceable>varid</replaceable>|</literal>
<indexterm><primary>quasi-quotation</primary></indexterm>
</term>
<listitem><para>
<replaceable>string</replaceable><literal>#</literal>,
<replaceable>integer</replaceable><literal>#</literal>,
<replaceable>float</replaceable><literal>#</literal>,
- <replaceable>float</replaceable><literal>##</literal>,
- <literal>(#</literal>, <literal>#)</literal>
+ <replaceable>float</replaceable><literal>##</literal>
</term>
<listitem><para>
Stolen by: <option>-XMagicHash</option>
</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>(#</literal>, <literal>#)</literal>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XUnboxedTuples</option>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <replaceable>varid</replaceable><literal>!</literal><replaceable>varid</replaceable>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XBangPatterns</option>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>pattern</literal>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XPatternSynonyms</option>
+ </para></listitem>
+ </varlistentry>
</variablelist>
</para>
</sect2>
the following mal-formedness which isn't detected simply by kind checking:
<itemizedlist>
<listitem><para>
-Type constructor applied to a type involving for-alls.
-</para></listitem>
-<listitem><para>
-Unboxed tuple on left of an arrow.
+Type constructor applied to a type involving for-alls (if <literal>XImpredicativeTypes</literal>
+is off)
</para></listitem>
<listitem><para>
Partially-applied type synonym.
</para></listitem>
</itemizedlist>
-So, for example,
-this will be rejected:
+So, for example, this will be rejected:
<programlisting>
- type Pr = (# Int, Int #)
+ type Pr = forall a. a
- h :: Pr -> Int
- h x = ...
+ h :: [Pr]
+ h = ...
</programlisting>
-because GHC does not allow unboxed tuples on the left of a function arrow.
+because GHC does not allow type constructors applied to for-all types.
</para>
</sect2>
</programlisting>
The syntax is identical to that of an ordinary instance declaration apart from (a) the keyword
<literal>deriving</literal>, and (b) the absence of the <literal>where</literal> part.
-Note the following points:
+</para>
+<para>
+However, standalone deriving differs from a <literal>deriving</literal> clause in a number
+of important ways:
<itemizedlist>
+<listitem><para>The standalone deriving declaration does not need to be in the
+same module as the data type declaration. (But be aware of the dangers of
+orphan instances (<xref linkend="orphan-modules"/>).
+</para></listitem>
+
<listitem><para>
You must supply an explicit context (in the example the context is <literal>(Eq a)</literal>),
exactly as you would in an ordinary instance declaration.
</para></listitem>
<listitem><para>
-A <literal>deriving instance</literal> declaration
-must obey the same rules concerning form and termination as ordinary instance declarations,
-controlled by the same flags; see <xref linkend="instance-decls"/>.
-</para></listitem>
-
-<listitem><para>
Unlike a <literal>deriving</literal>
declaration attached to a <literal>data</literal> declaration, the instance can be more specific
than the data type (assuming you also use
GHC does not restrict the form of the data type. Instead, GHC simply generates the appropriate
boilerplate code for the specified class, and typechecks it. If there is a type error, it is
your problem. (GHC will show you the offending code if it has a type error.)
+</para>
+<para>
The merit of this is that you can derive instances for GADTs and other exotic
data types, providing only that the boilerplate code does indeed typecheck. For example:
<programlisting>
because <literal>T</literal> is a GADT, but you <emphasis>can</emphasis> generate
the instance declaration using stand-alone deriving.
</para>
+<para>
+The down-side is that,
+if the boilerplate code fails to typecheck, you will get an error message about that
+code, which you did not write. Whereas, with a <literal>deriving</literal> clause
+the side-conditions are necessarily more conservative, but any error message
+may be more comprehensible.
+</para>
</listitem>
+</itemizedlist></para>
+
+<para>
+In other ways, however, a standalone deriving obeys the same rules as ordinary deriving:
+<itemizedlist>
+<listitem><para>
+A <literal>deriving instance</literal> declaration
+must obey the same rules concerning form and termination as ordinary instance declarations,
+controlled by the same flags; see <xref linkend="instance-decls"/>.
+</para></listitem>
<listitem>
<para>The stand-alone syntax is generalised for newtypes in exactly the same
</sect2>
-
-<sect2 id="deriving-typeable">
-<title>Deriving clause for extra classes (<literal>Typeable</literal>, <literal>Data</literal>, etc)</title>
+<sect2 id="deriving-extra">
+<title>Deriving instances of extra classes (<literal>Data</literal>, etc)</title>
<para>
Haskell 98 allows the programmer to add "<literal>deriving( Eq, Ord )</literal>" to a data type
<para>
GHC extends this list with several more classes that may be automatically derived:
<itemizedlist>
-<listitem><para> With <option>-XDeriveDataTypeable</option>, you can derive instances of the classes
-<literal>Typeable</literal>, and <literal>Data</literal>, defined in the library
-modules <literal>Data.Typeable</literal> and <literal>Data.Generics</literal> respectively.
-</para>
-<para>Since GHC 7.8.1, <literal>Typeable</literal> is kind-polymorphic (see
-<xref linkend="kind-polymorphism"/>) and can be derived for any datatype and
-type class. Instances for datatypes can be derived by attaching a
-<literal>deriving Typeable</literal> clause to the datatype declaration, or by
-using standalone deriving (see <xref linkend="stand-alone-deriving"/>).
-Instances for type classes can only be derived using standalone deriving.
-For data families, <literal>Typeable</literal> should only be derived for the
-uninstantiated family type; each instance will then automatically have a
-<literal>Typeable</literal> instance too.
-See also <xref linkend="auto-derive-typeable"/>.
-</para>
-<para>
-Also since GHC 7.8.1, handwritten (ie. not derived) instances of
-<literal>Typeable</literal> are forbidden, and will result in an error.
-</para>
-</listitem>
-
<listitem><para> With <option>-XDeriveGeneric</option>, you can derive
instances of the classes <literal>Generic</literal> and
<literal>Generic1</literal>, defined in <literal>GHC.Generics</literal>.
defined in <literal>GHC.Base</literal>.
</para></listitem>
+<listitem><para> With <option>-XDeriveDataTypeable</option>, you can derive instances of
+the class <literal>Data</literal>,
+defined in <literal>Data.Data</literal>. See <xref linkend="deriving-typeable"/> for
+deriving <literal>Typeable</literal>.
+</para></listitem>
+
<listitem><para> With <option>-XDeriveFoldable</option>, you can derive instances of
the class <literal>Foldable</literal>,
defined in <literal>Data.Foldable</literal>.
<listitem><para> With <option>-XDeriveTraversable</option>, you can derive instances of
the class <literal>Traversable</literal>,
-defined in <literal>Data.Traversable</literal>.
+defined in <literal>Data.Traversable</literal>. Since the <literal>Traversable</literal>
+instance dictates the instances of <literal>Functor</literal> and
+<literal>Foldable</literal>, you'll probably want to derive them too, so
+<option>-XDeriveTraversable</option> implies
+<option>-XDeriveFunctor</option> and <option>-XDeriveFoldable</option>.
</para></listitem>
</itemizedlist>
+You can also use a standalone deriving declaration instead
+(see <xref linkend="stand-alone-deriving"/>).
+</para>
+<para>
In each case the appropriate class must be in scope before it
can be mentioned in the <literal>deriving</literal> clause.
</para>
</sect2>
-<sect2 id="auto-derive-typeable">
-<title>Automatically deriving <literal>Typeable</literal> instances</title>
+<sect2 id="deriving-typeable">
+<title>Deriving <literal>Typeable</literal> instances</title>
-<para>
+<para>The class <literal>Typeable</literal> is very special:
+<itemizedlist>
+<listitem><para>
+<literal>Typeable</literal> is kind-polymorphic (see
+<xref linkend="kind-polymorphism"/>).
+</para></listitem>
+
+<listitem><para>
+Only derived instances of <literal>Typeable</literal> are allowed;
+i.e. handwritten instances are forbidden. This ensures that the
+programmer cannot subert the type system by writing bogus instances.
+</para></listitem>
+
+<listitem><para>
+With <option>-XDeriveDataTypeable</option>
+GHC allows you to derive instances of <literal>Typeable</literal> for data types or newtypes,
+using a <literal>deriving</literal> clause, or using
+a standalone deriving declaration (<xref linkend="stand-alone-deriving"/>).
+</para></listitem>
+
+<listitem><para>
+With <option>-XDataKinds</option>, deriving <literal>Typeable</literal> for a data
+type (whether via a deriving clause or standalone deriving)
+also derives <literal>Typeable</literal> for the promoted data constructors (<xref linkend="promotion"/>).
+</para></listitem>
+
+<listitem><para>
+However, using standalone deriving, you can <emphasis>also</emphasis> derive
+a <literal>Typeable</literal> instance for a data family.
+You may not add a <literal>deriving(Typeable)</literal> clause to a
+<literal>data instance</literal> declaration; instead you must use a
+standalone deriving declaration for the data family.
+</para></listitem>
+
+<listitem><para>
+Using standalone deriving, you can <emphasis>also</emphasis> derive
+a <literal>Typeable</literal> instance for a type class.
+</para></listitem>
+
+<listitem><para>
The flag <option>-XAutoDeriveTypeable</option> triggers the generation
-of derived <literal>Typeable</literal> instances for every datatype and type
-class declaration in the module it is used. It will also generate
-<literal>Typeable</literal> instances for any promoted data constructors
-(<xref linkend="promotion"/>). This flag implies
-<option>-XDeriveDataTypeable</option> (<xref linkend="deriving-typeable"/>).
+of derived <literal>Typeable</literal> instances for every datatype, data family,
+and type class declaration in the module it is used, unless a manually-specified one is
+already provided.
+This flag implies <option>-XDeriveDataTypeable</option>.
+</para></listitem>
+</itemizedlist>
+
</para>
</sect2>
<sect3> <title> A more precise specification </title>
<para>
-Derived instance declarations are constructed as follows. Consider the
-declaration (after expansion of any type synonyms)
+A derived instance is derived only for declarations of these forms (after expansion of any type synonyms)
<programlisting>
- newtype T v1...vn = T' (t vk+1...vn) deriving (c1...cm)
+ newtype T v1..vn = MkT (t vk+1..vn) deriving (C t1..tj)
+ newtype instance T s1..sk vk+1..vn = MkT (t vk+1..vn) deriving (C t1..tj)
</programlisting>
-
where
<itemizedlist>
<listitem><para>
- The <literal>ci</literal> are partial applications of
- classes of the form <literal>C t1'...tj'</literal>, where the arity of <literal>C</literal>
+<literal>v1..vn</literal> are type variables, and <literal>t</literal>,
+<literal>s1..sk</literal>, <literal>t1..tj</literal> are types.
+</para></listitem>
+<listitem><para>
+ The <literal>(C t1..tj)</literal> is a partial applications of the class <literal>C</literal>,
+ where the arity of <literal>C</literal>
is exactly <literal>j+1</literal>. That is, <literal>C</literal> lacks exactly one type argument.
</para></listitem>
<listitem><para>
- The <literal>k</literal> is chosen so that <literal>ci (T v1...vk)</literal> is well-kinded.
+ <literal>k</literal> is chosen so that <literal>C t1..tj (T v1...vk)</literal> is well-kinded.
+(Or, in the case of a <literal>data instance</literal>, so that <literal>C t1..tj (T s1..sk)</literal> is
+well kinded.)
</para></listitem>
<listitem><para>
The type <literal>t</literal> is an arbitrary type.
</para></listitem>
<listitem><para>
- The type variables <literal>vk+1...vn</literal> do not occur in <literal>t</literal>,
- nor in the <literal>ci</literal>, and
+ The type variables <literal>vk+1...vn</literal> do not occur in the types <literal>t</literal>,
+ <literal>s1..sk</literal>, or <literal>t1..tj</literal>.
</para></listitem>
<listitem><para>
- None of the <literal>ci</literal> is <literal>Read</literal>, <literal>Show</literal>,
+ <literal>C</literal> is not <literal>Read</literal>, <literal>Show</literal>,
<literal>Typeable</literal>, or <literal>Data</literal>. These classes
should not "look through" the type or its constructor. You can still
derive these classes for a newtype, but it happens in the usual way, not
via this new mechanism.
</para></listitem>
<listitem><para>
- The role of the last parameter of each of the <literal>ci</literal> is <emphasis>not</emphasis> <literal>N</literal>. (See <xref linkend="roles"/>.)</para></listitem>
+ It is safe to coerce each of the methods of <literal>C</literal>. That is,
+ the missing last argument to <literal>C</literal> is not used
+ at a nominal role in any of the <literal>C</literal>'s methods.
+ (See <xref linkend="roles"/>.)</para></listitem>
</itemizedlist>
-Then, for each <literal>ci</literal>, the derived instance
+Then the derived instance is of form
declaration is:
<programlisting>
- instance ci t => ci (T v1...vk)
+ instance C t1..tj t => C t1..tj (T v1...vk)
</programlisting>
As an example which does <emphasis>not</emphasis> work, consider
<programlisting>
<sect3 id="nullary-type-classes">
<title>Nullary type classes</title>
-Nullary (no parameter) type classes are enabled with <option>-XNullaryTypeClasses</option>.
+Nullary (no parameter) type classes are enabled with
+<option>-XMultiTypeClasses</option>; historically, they were enabled with the
+(now deprecated) <option>-XNullaryTypeClasses</option>.
Since there are no available parameters, there can be at most one instance
of a nullary class. A nullary type class might be used to document some assumption
in a type signature (such as reliance on the Riemann hypothesis) or add some
fromListN _ = fromList
</programlisting>
-<para>The <literal>FromList</literal> class and its methods are intended to be
+<para>The <literal>IsList</literal> class and its methods are intended to be
used in conjunction with the <option>OverloadedLists</option> extension.
<itemizedlist>
<listitem> <para> The type function
useful for completely new data types.
Here are several example instances:
<programlisting>
-instance FromList [a] where
+instance IsList [a] where
type Item [a] = a
fromList = id
toList = id
-instance (Ord a) => FromList (Set a) where
+instance (Ord a) => IsList (Set a) where
type Item (Set a) = a
fromList = Set.fromList
toList = Set.toList
-instance (Ord k) => FromList (Map k v) where
+instance (Ord k) => IsList (Map k v) where
type Item (Map k v) = (k,v)
fromList = Map.fromList
toList = Map.toList
-instance FromList (IntMap v) where
+instance IsList (IntMap v) where
type Item (IntMap v) = (Int,v)
fromList = IntMap.fromList
toList = IntMap.toList
-instance FromList Text where
+instance IsList Text where
type Item Text = Char
fromList = Text.pack
toList = Text.unpack
-instance FromList (Vector a) where
+instance IsList (Vector a) where
type Item (Vector a) = a
fromList = Vector.fromList
fromListN = Vector.fromListN
type Elem ce :: *
...
</programlisting>
-When doing so, we drop the "<literal>family</literal>" keyword.
+When doing so, we (optionally) may drop the "<literal>family</literal>" keyword.
</para>
<para>
The type parameters must all be type variables, of course,
<title>Associated instances</title>
<para>
When an associated data or type synonym family instance is declared within a type
- class instance, we drop the <literal>instance</literal> keyword in the
+ class instance, we (optionally) may drop the <literal>instance</literal> keyword in the
family instance:
<programlisting>
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where
<programlisting>
class IsBoolMap v where
type Key v
- type Key v = Int
+ type instance Key v = Int
lookupKey :: Key v -> v -> Maybe Bool
instance IsBoolMap [(Int, Bool)] where
lookupKey = lookup
</programlisting>
-
+The <literal>instance</literal> keyword is optional.
+ </para>
+<para>
There can also be multiple defaults for a single type, as long as they do not
overlap:
<programlisting>
type safety.
</para>
</sect3>
+
+ <sect3><title>Instance contexts and associated type and data instances</title>
+ <para>Associated type and data instance declarations do not inherit any
+ context specified on the enclosing instance. For type instance declarations,
+ it is unclear what the context would mean. For data instance declarations,
+ it is unlikely a user would want the context repeated for every data constructor.
+ The only place where the context might likely be useful is in a
+ <literal>deriving</literal> clause of an associated data instance. However,
+ even here, the role of the outer instance context is murky. So, for
+ clarity, we just stick to the rule above: the enclosing instance context
+ is ignored. If you need to use
+ a non-trivial context on a derived instance,
+ use a <link linkend="stand-alone-deriving">standalone
+ deriving</link> clause (at the top level).
+ </para>
+ </sect3>
+
</sect2>
<sect2 id="data-family-import-export">
</para>
</sect2>
+
+<sect2><title>Kind inference in class instance declarations</title>
+
+<para>Consider the following example of a poly-kinded class and an instance for it:</para>
+
+<programlisting>
+class C a where
+ type F a
+
+instance C b where
+ type F b = b -> b
+</programlisting>
+
+<para>In the class declaration, nothing constrains the kind of the type
+<literal>a</literal>, so it becomes a poly-kinded type variable <literal>(a :: k)</literal>.
+Yet, in the instance declaration, the right-hand side of the associated type instance
+<literal>b -> b</literal> says that <literal>b</literal> must be of kind <literal>*</literal>. GHC could theoretically propagate this information back into the instance head, and
+make that instance declaration apply only to type of kind <literal>*</literal>, as opposed
+to types of any kind. However, GHC does <emphasis>not</emphasis> do this.</para>
+
+<para>In short: GHC does <emphasis>not</emphasis> propagate kind information from
+the members of a class instance declaration into the instance declaration head.</para>
+
+<para>This lack of kind inference is simply an engineering problem within GHC, but
+getting it to work would make a substantial change to the inference infrastructure,
+and it's not clear the payoff is worth it. If you want to restrict <literal>b</literal>'s
+kind in the instance above, just use a kind signature in the instance head.</para>
+
+</sect2>
</sect1>
<sect1 id="promotion">
</para>
</sect2>
-<sect2 id="promoted-literals">
-<title>Promoted Literals</title>
+<sect2 id="promotion-existentials">
+<title>Promoting existential data constructors</title>
<para>
-Numeric and string literals are promoted to the type level, giving convenient
-access to a large number of predefined type-level constants. Numeric literals
-are of kind <literal>Nat</literal>, while string literals are of kind
-<literal>Symbol</literal>. These kinds are defined in the module
-<literal>GHC.TypeLits</literal>.
+Note that we do promote existential data constructors that are otherwise suitable.
+For example, consider the following:
+<programlisting>
+data Ex :: * where
+ MkEx :: forall a. a -> Ex
+</programlisting>
+Both the type <literal>Ex</literal> and the data constructor <literal>MkEx</literal>
+get promoted, with the polymorphic kind <literal>'MkEx :: forall k. k -> Ex</literal>.
+Somewhat surprisingly, you can write a type family to extract the member
+of a type-level existential:
+<programlisting>
+type family UnEx (ex :: Ex) :: k
+type instance UnEx (MkEx x) = x
+</programlisting>
+At first blush, <literal>UnEx</literal> seems poorly-kinded. The return kind
+<literal>k</literal> is not mentioned in the arguments, and thus it would seem
+that an instance would have to return a member of <literal>k</literal>
+<emphasis>for any</emphasis> <literal>k</literal>. However, this is not the
+case. The type family <literal>UnEx</literal> is a kind-indexed type family.
+The return kind <literal>k</literal> is an implicit parameter to <literal>UnEx</literal>.
+The elaborated definitions are as follows:
+<programlisting>
+type family UnEx (k :: BOX) (ex :: Ex) :: k
+type instance UnEx k (MkEx k x) = x
+</programlisting>
+Thus, the instance triggers only when the implicit parameter to <literal>UnEx</literal>
+matches the implicit parameter to <literal>MkEx</literal>. Because <literal>k</literal>
+is actually a parameter to <literal>UnEx</literal>, the kind is not escaping the
+existential, and the above code is valid.
+</para>
+
+<para>
+See also <ulink url="http://ghc.haskell.org/trac/ghc/ticket/7347">Trac #7347</ulink>.
+</para>
+</sect2>
+
+<sect2>
+<title>Promoting type operators</title>
+<para>
+Type operators are <emphasis>not</emphasis> promoted to the kind level. Why not? Because
+<literal>*</literal> is a kind, parsed the way identifiers are. Thus, if a programmer
+tried to write <literal>Either * Bool</literal>, would it be <literal>Either</literal>
+applied to <literal>*</literal> and <literal>Bool</literal>? Or would it be
+<literal>*</literal> applied to <literal>Either</literal> and <literal>Bool</literal>.
+To avoid this quagmire, we simply forbid promoting type operators to the kind level.
+</para>
+</sect2>
+
+
+</sect1>
+
+<sect1 id="type-level-literals">
+<title>Type-Level Literals</title>
+<para>
+GHC supports numeric and string literals at the type level, giving convenient
+access to a large number of predefined type-level constants.
+Numeric literals are of kind <literal>Nat</literal>, while string literals
+are of kind <literal>Symbol</literal>.
+This feature is enabled by the <literal>XDataKinds</literal>
+language extension.
+</para>
+
+<para>
+The kinds of the literals and all other low-level operations for this feature
+are defined in module <literal>GHC.TypeLits</literal>. Note that the module
+defines some type-level operators that clash with their value-level
+counterparts (e.g. <literal>(+)</literal>). Import and export declarations
+referring to these operators require an explicit namespace
+annotation (see <xref linkend="explicit-namespaces"/>).
</para>
<para>
example = from (Point 1 2) (Get :: Label "x")
</programlisting>
</para>
-</sect2>
-<sect2 id="promotion-existentials">
-<title>Promoting existential data constructors</title>
+<sect2 id="typelit-runtime">
+<title>Runtime Values for Type-Level Literals</title>
<para>
-Note that we do promote existential data constructors that are otherwise suitable.
-For example, consider the following:
+Sometimes it is useful to access the value-level literal assocaited with
+a type-level literal. This is done with the functions
+<literal>natVal</literal> and <literal>symbolVal</literal>. For example:
<programlisting>
-data Ex :: * where
- MkEx :: forall a. a -> Ex
+GHC.TypeLits> natVal (Proxy :: Proxy 2)
+2
</programlisting>
-Both the type <literal>Ex</literal> and the data constructor <literal>MkEx</literal>
-get promoted, with the polymorphic kind <literal>'MkEx :: forall k. k -> Ex</literal>.
-Somewhat surprisingly, you can write a type family to extract the member
-of a type-level existential:
+These functions are overloaded because they need to return a different
+result, depending on the type at which they are instantiated.
<programlisting>
-type family UnEx (ex :: Ex) :: k
-type instance UnEx (MkEx x) = x
+natVal :: KnownNat n => proxy n -> Integer
+
+-- instance KnownNat 0
+-- instance KnownNat 1
+-- instance KnownNat 2
+-- ...
</programlisting>
-At first blush, <literal>UnEx</literal> seems poorly-kinded. The return kind
-<literal>k</literal> is not mentioned in the arguments, and thus it would seem
-that an instance would have to return a member of <literal>k</literal>
-<emphasis>for any</emphasis> <literal>k</literal>. However, this is not the
-case. The type family <literal>UnEx</literal> is a kind-indexed type family.
-The return kind <literal>k</literal> is an implicit parameter to <literal>UnEx</literal>.
-The elaborated definitions are as follows:
+GHC discharges the constraint as soon as it knows what concrete
+type-level literal is being used in the program. Note that this works
+only for <emphasis>literals</emphasis> and not arbitrary type expressions.
+For example, a constraint of the form <literal>KnownNat (a + b)</literal>
+will <emphasis>not</emphasis> be simplified to
+<literal>(KnownNat a, KnownNat b)</literal>; instead, GHC will keep the
+constraint as is, until it can simplify <literal>a + b</literal> to
+a constant value.
+</para>
+</sect2>
+
+<para>
+It is also possible to convert a run-time integer or string value to
+the corresponding type-level literal. Of course, the resulting type
+literal will be unknown at compile-time, so it is hidden in an existential
+type. The conversion may be performed using <literal>someNatVal</literal>
+for integers and <literal>someSymbolVal</literal> for strings:
<programlisting>
-type family UnEx (k :: BOX) (ex :: Ex) :: k
-type instance UnEx k (MkEx k x) = x
+someNatVal :: Integer -> Maybe SomeNat
+SomeNat :: KnownNat n => Proxy n -> SomeNat
</programlisting>
-Thus, the instance triggers only when the implicit parameter to <literal>UnEx</literal>
-matches the implicit parameter to <literal>MkEx</literal>. Because <literal>k</literal>
-is actually a parameter to <literal>UnEx</literal>, the kind is not escaping the
-existential, and the above code is valid.
+The operations on strings are similar.
</para>
+<sect2 id="typelit-tyfuns">
+<title>Computing With Type-Level Naturals</title>
+<para>
+GHC 7.8 can evaluate arithmetic expressions involving type-level natural
+numbers. Such expressions may be constructed using the type-families
+<literal>(+), (*), (^)</literal> for addition, multiplication,
+and exponentiation. Numbers may be compared using <literal>(<=?)</literal>,
+which returns a promoted boolean value, or <literal>(<=)</literal>, which
+compares numbers as a constraint. For example:
+<programlisting>
+GHC.TypeLits> natVal (Proxy :: Proxy (2 + 3))
+5
+</programlisting>
+</para>
<para>
-See also <ulink url="http://hackage.haskell.org/trac/ghc/ticket/7347">Trac #7347</ulink>.
+At present, GHC is quite limited in its reasoning about arithmetic:
+it will only evalute the arithmetic type functions and compare the results---
+in the same way that it does for any other type function. In particular,
+it does not know more general facts about arithmetic, such as the commutativity
+and associativity of <literal>(+)</literal>, for example.
+</para>
+
+<para>
+However, it is possible to perform a bit of "backwards" evaluation.
+For example, here is how we could get GHC to compute arbitrary logarithms
+at the type level:
+<programlisting>
+lg :: Proxy base -> Proxy (base ^ pow) -> Proxy pow
+lg _ _ = Proxy
+
+GHC.TypeLits> natVal (lg (Proxy :: Proxy 2) (Proxy :: Proxy 8))
+3
+</programlisting>
</para>
</sect2>
with the class head. Method signatures are not affected by that
process.
</para>
+
+ <sect2 id="coercible">
+ <title>The <literal>Coercible</literal> constraint</title>
+ <para>
+ The constraint <literal>Coercible t1 t2</literal> is similar to <literal>t1 ~
+ t2</literal>, but denotes representational equality between
+ <literal>t1</literal> and <literal>t2</literal> in the sense of Roles
+ (<xref linkend="roles"/>). It is exported by
+ <ulink url="&libraryBaseLocation;/Data-Coerce.html"><literal>Data.Coerce</literal></ulink>,
+ which also contains the documentation. More details and discussion can be found in
+ the paper
+ <ulink href="http://www.cis.upenn.edu/~eir/papers/2014/coercible/coercible.pdf">Safe Coercions"</ulink>.
+ </para>
+ </sect2>
+
</sect1>
<sect1 id="constraint-kind">
type <literal>(Show a, Ord a)</literal> is of kind <literal>Constraint</literal>.
</listitem>
<listitem>
- Anything whose form is not yet know, but the user has declared to have kind <literal>Constraint</literal>.
- So for example <literal>type Foo (f :: * -> Constraint) = forall b. f b => b -> b</literal> is allowed, as
- well as examples involving type families:
+ Anything whose form is not yet know, but the user has declared to have kind <literal>Constraint</literal>
+ (for which they need to import it from <literal>GHC.Exts</literal>). So for example
+ <literal>type Foo (f :: * -> Constraint) = forall b. f b => b -> b</literal> is allowed, as well as
+ examples involving type families:
<programlisting>
type family Typ a b :: Constraint
type instance Typ Int b = Show b
The <option>-XFlexibleContexts</option> flag lifts the Haskell 98 restriction
that the type-class constraints in a type signature must have the
form <emphasis>(class type-variable)</emphasis> or
-<emphasis>(class (type-variable type-variable ...))</emphasis>.
+<emphasis>(class (type-variable type1 type2 ... typen))</emphasis>.
With <option>-XFlexibleContexts</option>
these type signatures are perfectly OK
<programlisting>
</programlisting>
The idea is there can be no legal calls to <literal>f</literal> because every call will
give rise to an ambiguous constraint.
-</para>
-<para>
-The <emphasis>only</emphasis> purpose of the
+Indeed, the <emphasis>only</emphasis> purpose of the
ambiguity check is to report functions that cannot possibly be called.
We could soundly omit the
ambiguity check on type signatures entirely, at the expense of
But in fact <literal>f</literal>'s type
is instantiated and the instantiated constraints are solved against
the constraints bound by <literal>g</literal>'s signature. So, in the case an ambiguous type, solving will fail.
-For example, consider the earlier definition <literal>f :: C a => Int</literal>. Then in <literal>g</literal>'s definition,
-we'll instantiate to <literal>(C alpha)</literal> and try to
+For example, consider the earlier definition <literal>f :: C a => Int</literal>:
+<programlisting>
+ f :: C a => Int
+ f = ...blah...
+
+ g :: C a => Int
+ g = f
+</programlisting>
+In <literal>g</literal>'s definition,
+we'll instantiate to <literal>(C alpha)</literal> and try to
deduce <literal>(C alpha)</literal> from <literal>(C a)</literal>,
-and fail.
+and fail.
</para>
<para>
-So in fact we use this as our <emphasis>definition</emphasis> of ambiguity: a type
+So in fact we use this as our <emphasis>definition</emphasis> of ambiguity: a type
<literal><replaceable>ty</replaceable></literal> is
-ambiguious if and only if <literal>((undefined :: <replaceable>ty</replaceable>)
+ambiguious if and only if <literal>((undefined :: <replaceable>ty</replaceable>)
:: <replaceable>ty</replaceable>)</literal> would fail to typecheck. We use a
very similar test for <emphasis>inferred</emphasis> types, to ensure that they too are
-unambiguous.
+unambiguous.
+</para>
+<para><emphasis>Switching off the ambiguity check.</emphasis>
+Even if a function is has an ambiguous type according the "guiding principle",
+it is possible that the function is callable. For example:
+<programlisting>
+ class D a b where ...
+ instance D Bool b where ...
+
+ strange :: D a b => a -> a
+ strange = ...blah...
+
+ foo = strange True
+</programlisting>
+Here <literal>strange</literal>'s type is ambiguous, but the call in <literal>foo</literal>
+is OK because it gives rise to a constraint <literal>(D Bool beta)</literal>, which is
+soluble by the <literal>(D Bool b)</literal> instance. So the language extension
+<option>-XAllowAmbiguousTypes</option> allows you to switch off the ambiguity check.
+But even with ambiguity checking switched off, GHC will complain about a function
+that can <emphasis>never</emphasis> be called, such as this one:
+<programlisting>
+ f :: (Int ~ Bool) => a -> a
+</programlisting>
</para>
<para>
constructor <function>MkSwizzle</function>, an implicit "<literal>forall a.</literal>" is
prefixed to the argument type. The implicit <literal>forall</literal>
quantifies all type variables that are not already in scope, and are
-mentioned in the type quantified over.
+mentioned in the type quantified over. (Arguably, it would be better
+to <emphasis>require</emphasis> explicit quantification on constructor arguments
+where that is what is wanted.
+See <ulink url="http://ghc.haskell.org/trac/ghc/ticket/4426">Trac #4426</ulink>.)
+
</para>
<para>
types too. So if you write this:
<programlisting>
- data T a = MkT (Either a b) (b -> b)
+ f :: (a -> a) -> a
</programlisting>
it's just as if you had written this:
<programlisting>
- data T a = MkT (forall b. Either a b) (forall b. b -> b)
+ f :: forall a. (a -> a) -> a
</programlisting>
-That is, since the type variable <literal>b</literal> isn't in scope, it's
-implicitly universally quantified. (Arguably, it would be better
-to <emphasis>require</emphasis> explicit quantification on constructor arguments
-where that is what is wanted. Feedback welcomed.)
+That is, since the type variable <literal>a</literal> isn't in scope, it's
+implicitly universally quantified.
</para>
<para>
4.5.5</ulink>
of the Haskell Report)
can be completely switched off by
-<option>-XNoMonomorphismRestriction</option>.
+<option>-XNoMonomorphismRestriction</option>. Since GHC 7.8.1, the monomorphism
+restriction is switched off by default in GHCi.
</para>
</sect3>
<para>
An ML-style language usually generalises the type of any let-bound or where-bound variable,
so that it is as polymorphic as possible.
-With the flag <option>-XMonoLocalBinds</option> GHC implements a slightly more conservative policy:
-<emphasis>it generalises only "closed" bindings</emphasis>.
-A binding is considered "closed" if either
+With the flag <option>-XMonoLocalBinds</option> GHC implements a slightly more conservative policy,
+using the following rules:
<itemizedlist>
-<listitem><para>It is one of the top-level bindings of a module, or </para></listitem>
-<listitem><para>Its free variables are all themselves closed</para></listitem>
+ <listitem><para>
+ A variable is <emphasis>closed</emphasis> if and only if
+ <itemizedlist>
+ <listitem><para> the variable is let-bound</para></listitem>
+ <listitem><para> one of the following holds:
+ <itemizedlist>
+ <listitem><para>the variable has an explicit type signature that has no free type variables, or</para></listitem>
+ <listitem><para>its binding group is fully generalised (see next bullet) </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+
+ <listitem><para>
+ A binding group is <emphasis>fully generalised</emphasis> if and only if
+ <itemizedlist>
+ <listitem><para>each of its free variables is either imported or closed, and</para></listitem>
+ <listitem><para>the binding is not affected by the monomorphism restriction
+ (<ulink url="http://www.haskell.org/onlinereport/decls.html#sect4.5.5">Haskell Report, Section 4.5.5</ulink>)</para></listitem>
+ </itemizedlist>
+ </para></listitem>
</itemizedlist>
For example, consider
<programlisting>
k z = z+x
in h x + k x
</programlisting>
-Here <literal>f</literal> and <literal>g</literal> are closed because they are bound at top level.
-Also <literal>h</literal> is closed because its only free variable <literal>f</literal> is closed.
-But <literal>k</literal> is not closed because it mentions <literal>x</literal> which is locally bound.
-Another way to think of it is this: all closed bindings <literal>could</literal> be defined at top level.
-(In the example, we could move <literal>h</literal> to top level.)
-</para><para>
-All of this applies only to bindings that lack an explicit type signature, so that GHC has to
-infer its type. If you supply a type signature, then that fixes type of the binding, end of story.
-</para><para>
+Here <literal>f</literal> is generalised because it has no free variables; and its binding group
+is unaffected by the monomorphism restriction; and hence <literal>f</literal> is closed.
+The same reasoning applies to <literal>g</literal>, except that it has one closed free variable, namely <literal>f</literal>.
+Similarly <literal>h</literal> is closed, <emphasis>even though it is not bound at top level</emphasis>,
+because its only free variable <literal>f</literal> is closed.
+But <literal>k</literal> is not closed, because it mentions <literal>x</literal> which is not closed (because it is not let-bound).
+</para>
+<para>
+Notice that a top-level binding that is affected by the monomorphism restriction is not closed, and hence may
+in turn prevent generalisation of bindings that mention it.
+</para>
+<para>
The rationale for this more conservative strategy is given in
<ulink url="http://research.microsoft.com/~simonpj/papers/constraints/index.htm">the papers</ulink> "Let should not be generalised" and "Modular type inference with local assumptions", and
-a related <ulink url="http://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7">blog post</ulink>.
+a related <ulink url="http://ghc.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7">blog post</ulink>.
</para><para>
The flag <option>-XMonoLocalBinds</option> is implied by <option>-XTypeFamilies</option> and <option>-XGADTs</option>. You can switch it off again
with <option>-XNoMonoLocalBinds</option> but type inference becomes less predicatable if you do so. (Read the papers!)
</sect3>
</sect2>
-<sect2 id="type-holes">
-<title>Type Holes</title>
+</sect1>
+<!-- ==================== End of type system extensions ================= -->
-<para>Type hole support is enabled with the option
-<option>-XTypeHoles</option>.</para>
+<sect1 id="typed-holes">
+<title>Typed Holes</title>
-<para>
-The goal of the type holes extension is not to change the type system, but to help with writing Haskell
-code. Type holes can be used to obtain extra information from the type checker, which might otherwise be hard
-to get.
-Normally, the type checker is used to decide if a module is well typed or not. Using GHCi,
-users can inspect the (inferred) type signatures of all top-level bindings. However, determining the
-type of a single term is still hard. Yet while writing code, it could be helpful to know the type of
-the term you're about to write.
-</para>
+<para>Typed hole support is enabled with the option
+<option>-fwarn-typed-holes</option>, which is enabled by default.</para>
<para>
-This extension allows special placeholders, written with a leading underscore (e.g. "<literal>_</literal>",
+This option allows special placeholders, written with a leading underscore (e.g. "<literal>_</literal>",
"<literal>_foo</literal>", "<literal>_bar</literal>"), to be used as an expression.
During compilation these holes will generate an error message describing what type is expected there,
information about the origin of any free type variables, and a list of local bindings
</para>
<para>
+The goal of the typed holes warning is not to change the type system, but to help with writing Haskell
+code. Typed holes can be used to obtain extra information from the type checker, which might otherwise be hard
+to get.
+Normally, using GHCi, users can inspect the (inferred) type signatures of all top-level bindings.
+However, this method is less convenient with terms which are not defined on top-level or
+inside complex expressions. Holes allow to check the type of the term you're about to write.
+</para>
+
+<para>
Holes work together well with <link linkend="defer-type-errors">deferring type errors to runtime</link>:
with <literal>-fdefer-type-errors</literal>, the error from a hole is also deferred, effctively making the hole
typecheck just like <literal>undefined</literal>, but with the added benefit that it will show its warning message
</para>
<para>
-Multiple type holes can be used to find common type variables between expressions. For example:
+Multiple typed holes can be used to find common type variables between expressions. For example:
<programlisting>
sum :: [Int] -> Int
-sum xx = foldr _f _z xs
+sum xs = foldr _f _z xs
</programlisting>
Shows:
<programlisting>
holes.hs:2:15:
- Found hole `_f' with type: Int-> Int -> Int
+ Found hole `_f' with type: Int -> Int -> Int
In the first argument of `foldr', namely `_'
In the expression: foldr _a _b _c
In an equation for `sum': sum x = foldr _a _b _c
In the second argument of `(:)', namely `_x'
In the expression: _x : _x
In an equation for `cons': cons = _x : _x
-Failed, modules loaded: none.
</programlisting>
This ensures that an unbound identifier is never reported with a too polymorphic type, like
<literal>forall a. a</literal>, when used multiple times for types that can not be unified.
</para>
-</sect2>
-
</sect1>
-<!-- ==================== End of type system extensions ================= -->
+<!-- ==================== Deferring type errors ================= -->
<sect1 id="defer-type-errors">
<title>Deferring type errors to runtime</title>
</para>
<para>
For more motivation and details please refer to the <ulink
- url="http://hackage.haskell.org/trac/ghc/wiki/DeferErrorsToRuntime">HaskellWiki</ulink>
+ url="http://ghc.haskell.org/trac/ghc/wiki/DeferErrorsToRuntime">HaskellWiki</ulink>
page or the <ulink
url="http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/">original
paper</ulink>.
constructions. You need to use the flag
<option>-XTemplateHaskell</option>
<indexterm><primary><option>-XTemplateHaskell</option></primary>
- </indexterm>to switch these syntactic extensions on
- (<option>-XTemplateHaskell</option> is no longer implied by
- <option>-fglasgow-exts</option>).</para>
+ </indexterm>to switch these syntactic extensions on.</para>
<itemizedlist>
<listitem><para>
<itemizedlist>
<listitem><para> an expression; the spliced expression must
have type <literal>Q Exp</literal></para></listitem>
- <listitem><para> an type; the spliced expression must
- have type <literal>Q Typ</literal></para></listitem>
- <listitem><para> a list of top-level declarations; the spliced expression
+ <listitem><para> a pattern; the spliced pattern must
+ have type <literal>Q Pat</literal></para></listitem>
+ <listitem><para> a type; the spliced expression must
+ have type <literal>Q Type</literal></para></listitem>
+ <listitem><para> a list of declarations; the spliced expression
must have type <literal>Q [Dec]</literal></para></listitem>
</itemizedlist>
- Note that pattern splices are not supported.
Inside a splice you can only call functions defined in imported modules,
not functions defined elsewhere in the same module.</para></listitem>
the quotation has type <literal>Q Pat</literal>.</para></listitem>
</itemizedlist></para></listitem>
+ <listitem>
+ <para>
+ A <emphasis>typed</emphasis> expression splice is written
+ <literal>$$x</literal>, where <literal>x</literal> is an
+ identifier, or <literal>$$(...)</literal>, where the "..." is
+ an arbitrary expression.
+ </para>
+ <para>
+ A typed expression splice can occur in place of an
+ expression; the spliced expression must have type <literal>Q
+ (TExp a)</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <emphasis>typed</emphasis> expression quotation is written
+ as <literal>[|| ... ||]</literal>, or <literal>[e||
+ ... ||]</literal>, where the "..." is an expression; if the
+ "..." expression has type <literal>a</literal>, then the
+ quotation has type <literal>Q (TExp a)</literal>.
+ </para>
+
+ <para>
+ Values of type <literal>TExp a</literal> may be converted to
+ values of type <literal>Exp</literal> using the function
+ <literal>unType :: TExp a -> Exp</literal>.
+ </para>
+ </listitem>
+
<listitem><para>
A quasi-quotation can appear in either a pattern context or an
expression context and is also written in Oxford brackets:
</programlisting>
This abbreviation makes top-level declaration slices quieter and less intimidating.
</para></listitem>
+
+ <listitem>
+ <para>
+ Binders are lexically scoped. For example, consider the
+ following code, where a value <literal>g</literal> of type
+ <literal>Bool -> Q Pat</literal> is in scope, having been
+ imported from another module
+<programlisting>
+y :: Int
+y = 7
+
+f :: Int -> Int -> Int
+f n = \ $(g True) -> y+n
+</programlisting>
+ The <literal>y</literal> in the right-hand side of
+ <literal>f</literal> refers to the top-level <literal>y =
+ 7</literal>, even if the pattern splice <literal>$(g
+ n)</literal> also generates a binder <literal>y</literal>.
+ </para>
+
+ <para>
+ Note that a pattern quasiquoter <emphasis>may</emphasis>
+ generate binders that scope over the right-hand side of a
+ definition because these binders are in scope lexically. For
+ example, given a quasiquoter <literal>haskell</literal> that
+ parses Haskell, in the following code, the <literal>y</literal>
+ in the right-hand side of <literal>f</literal> refers to the
+ <literal>y</literal> bound by the <literal>haskell</literal>
+ pattern quasiquoter, <emphasis>not</emphasis> the top-level
+ <literal>y = 7</literal>.
+<programlisting>
+y :: Int
+y = 7
+
+f :: Int -> Int -> Int
+f n = \ [haskell|y|] -> y+n
+</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The type environment seen by <literal>reify</literal> includes
+ all the top-level declaration up to the end of the immediately
+ preceding <emphasis>declaration group</emphasis>, but no more.
+ </para>
+
+ <para>
+ A <emphasis>declaration group</emphasis> is the group of
+ declarations created by a top-level declaration splice, plus
+ those following it, down to but not including the next top-level
+ declaration splice. The first declaration group in a module
+ includes all top-level definitions down to but not including the
+ first top-level declaration splice.
+ </para>
+
+
+ <para>
+ Concretely, consider the following code
+<programlisting>
+module M where
+ import ...
+ f x = x
+ $(th1 4)
+ h y = k y y $(blah1)
+ $(th2 10)
+ w z = $(blah2)
+</programlisting>
+
+ In this example
+ <orderedlist>
+ <listitem>
+ <para>
+ A <literal>reify</literal> inside the splice <literal>$(th1
+ ..)</literal> would see the definition of
+ <literal>f</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <literal>reify</literal> inside the splice
+ <literal>$(blah1)</literal> would see the definition of
+ <literal>f</literal>, but would not see the definition of
+ <literal>h</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <literal>reify</literal> inside the splice
+ <literal>$(th2..)</literal> would see the definition of
+ <literal>f</literal>, all the bindings created by
+ <literal>$(th1..)</literal>, and the definition of
+ <literal>h</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <literal>reify</literal> inside the splice
+ <literal>$(blah2)</literal> would see the same definitions
+ as the splice <literal>$(th2...)</literal>.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </listitem>
</itemizedlist>
(Compared to the original paper, there are many differences of detail.
The syntax for a declaration splice uses "<literal>$</literal>" not "<literal>splice</literal>".
The type of the enclosed expression must be <literal>Q [Dec]</literal>, not <literal>[Q Dec]</literal>.
-Pattern splices and quotations are not implemented.)
+Typed expression splices and quotations are supported.)
</sect2>
quoter function interpret <literal>"|~]"</literal> as <literal>"|]"</literal>.
One way to implement this is to compose your quoter with a pre-processing pass to
perform your escape conversion. See the
-<ulink url="http://hackage.haskell.org/trac/ghc/ticket/5348">
+<ulink url="http://ghc.haskell.org/trac/ghc/ticket/5348">
discussion in Trac</ulink> for details.
</para></listitem>
</itemizedlist>
which is translated to
<screen>
arr (\ (x,y) -> if f x y then Left x else Right y) >>>
- (arr (\x -> x+1) >>> f) ||| (arr (\y -> y+2) >>> g)
+ (arr (\x -> x+1) >>> g) ||| (arr (\y -> y+2) >>> h)
</screen>
Since the translation uses <function>|||</function>,
the arrow concerned must belong to the <literal>ArrowChoice</literal> class.
patterns</emphasis>, written <literal>!<replaceable>pat</replaceable></literal>.
Bang patterns are under consideration for Haskell Prime.
The <ulink
-url="http://hackage.haskell.org/trac/haskell-prime/wiki/BangPatterns">Haskell
+url="http://ghc.haskell.org/trac/haskell-prime/wiki/BangPatterns">Haskell
prime feature description</ulink> contains more discussion and examples
than the material below.
</para>
<literal>e</literal>. You can also disable assertions using the
<option>-fignore-asserts</option>
option<indexterm><primary><option>-fignore-asserts</option></primary>
- </indexterm>.</para>
+ </indexterm>. The option <option>-fno-ignore-asserts</option> allows
+enabling assertions even when optimisation is turned on.
+</para>
<para>
Assertion failures can be caught, see the documentation for the
<para>Every language extension can also be turned into a command-line flag
by prefixing it with "<literal>-X</literal>"; for example <option>-XForeignFunctionInterface</option>.
- (Similarly, all "<literal>-X</literal>" flags can be written as <literal>LANGUAGE</literal> pragmas.
+ (Similarly, all "<literal>-X</literal>" flags can be written as <literal>LANGUAGE</literal> pragmas.)
</para>
<para>A list of all supported language extensions can be obtained by invoking
<option>-fno-warn-warnings-deprecations</option>.</para>
</sect2>
+ <sect2 id="minimal-pragma">
+ <title>MINIMAL pragma</title>
+ <indexterm><primary>MINIMAL</primary></indexterm>
+ <para>The MINIMAL pragma is used to specify the minimal complete definition of a class. I.e. specify which methods must be implemented by all instances. If an instance does not satisfy the minimal complete definition, then a warning is generated.
+ This can be useful when a class has methods with circular defaults. For example
+ </para>
+<programlisting>
+class Eq a where
+ (==) :: a -> a -> Bool
+ (/=) :: a -> a -> Bool
+ x == y = not (x /= y)
+ x /= y = not (x == y)
+ {-# MINIMAL (==) | (/=) #-}
+</programlisting>
+ <para>Without the MINIMAL pragma no warning would be generated for an instance that implements neither method.
+ </para>
+ <para>The syntax for minimal complete definition is:</para>
+<screen>
+mindef ::= name
+ | '(' mindef ')'
+ | mindef '|' mindef
+ | mindef ',' mindef
+</screen>
+ <para>A vertical bar denotes disjunction, i.e. one of the two sides is required.
+ A comma denotes conjunction, i.e. both sides are required.
+ Conjunction binds stronger than disjunction.</para>
+ <para>
+ If no MINIMAL pragma is given in the class declaration, it is just as if
+ a pragma <literal>{-# MINIMAL op1, op2, ..., opn #-}</literal> was given, where
+ the <literal>opi</literal> are the methods
+ (a) that lack a default method in the class declaration, and
+ (b) whose name that does not start with an underscore
+ (c.f. <option>-fwarn-missing-methods</option>, <xref linkend="options-sanity"/>).
+ </para>
+ <para>This warning can be turned off with the flag <option>-fno-warn-missing-methods</option>.</para>
+ </sect2>
+
<sect2 id="inline-noinline-pragma">
<title>INLINE and NOINLINE pragmas</title>
<title>INLINE pragma</title>
<indexterm><primary>INLINE</primary></indexterm>
- <para>GHC (with <option>-O</option>, as always) tries to
- inline (or “unfold”) functions/values that are
- “small enough,” thus avoiding the call overhead
- and possibly exposing other more-wonderful optimisations.
- Normally, if GHC decides a function is “too
- expensive” to inline, it will not do so, nor will it
- export that unfolding for other modules to use.</para>
+ <para>
+ GHC (with <option>-O</option>, as always) tries to inline
+ (or “unfold”) functions/values that are
+ “small enough,” thus avoiding the call overhead
+ and possibly exposing other more-wonderful optimisations.
+ GHC has a set of heuristics, tuned over a long period of
+ time using many benchmarks, that decide when it is
+ beneficial to inline a function at its call site. The
+ heuristics are designed to inline functions when it appears
+ to be beneficial to do so, but without incurring excessive
+ code bloat. If a function looks too big, it won't be
+ inlined, and functions larger than a certain size will not
+ even have their definition exported in the interface file.
+ Some of the thresholds that govern these heuristic decisions
+ can be changed using flags, see <xref linkend="options-f"
+ />.
+ </para>
+
+ <para>
+ Normally GHC will do a reasonable job of deciding by itself
+ when it is a good idea to inline a function. However,
+ sometimes you might want to override the default behaviour.
+ For example, if you have a key function that is important to
+ inline because it leads to further optimisations, but GHC
+ judges it to be too big to inline.
+ </para>
<para>The sledgehammer you can bring to bear is the
<literal>INLINE</literal><indexterm><primary>INLINE
and <literal>INLINABLE</literal> (<xref linkend="inlinable-pragma"/>)
pragmas.</para>
- <para>Note: the HBC compiler doesn't like <literal>INLINE</literal> pragmas,
- so if you want your code to be HBC-compatible you'll have to surround
- the pragma with C pre-processor directives
- <literal>#ifdef __GLASGOW_HASKELL__</literal>...<literal>#endif</literal>.</para>
-
</sect3>
<sect3 id="inlinable-pragma">
The pragma must occur inside the <literal>where</literal> part
of the instance declaration.
</para>
-<para>
-Compatible with HBC, by the way, except perhaps in the placement
-of the pragma.
-</para>
</sect2>
conjunction with <option>-O</option><footnote>in fact, UNPACK
has no effect without <option>-O</option>, for technical
reasons
- (see <ulink url="http://hackage.haskell.org/trac/ghc/ticket/5252">tick
+ (see <ulink url="http://ghc.haskell.org/trac/ghc/ticket/5252">tick
5252</ulink>)</footnote>, in order to expose
unfoldings to the compiler so the reboxing can be removed as
often as possible. For example:</para>
</sect2>
-<sect2 id="core-pragma">
- <title>CORE pragma</title>
-
- <indexterm><primary>CORE pragma</primary></indexterm>
- <indexterm><primary>pragma, CORE</primary></indexterm>
- <indexterm><primary>core, annotation</primary></indexterm>
-
-<para>
- The external core format supports <quote>Note</quote> annotations;
- the <literal>CORE</literal> pragma gives a way to specify what these
- should be in your Haskell source code. Syntactically, core
- annotations are attached to expressions and take a Haskell string
- literal as an argument. The following function definition shows an
- example:
-
-<programlisting>
-f x = ({-# CORE "foo" #-} show) ({-# CORE "bar" #-} x)
-</programlisting>
-
- Semantically, this is equivalent to:
-
-<programlisting>
-g x = show x
-</programlisting>
-</para>
-
-<para>
- However, when external core is generated (via
- <option>-fext-core</option>), there will be Notes attached to the
- expressions <function>show</function> and <varname>x</varname>.
- The core function declaration for <function>f</function> is:
-</para>
-
-<programlisting>
- f :: %forall a . GHCziShow.ZCTShow a ->
- a -> GHCziBase.ZMZN GHCziBase.Char =
- \ @ a (zddShow::GHCziShow.ZCTShow a) (eta::a) ->
- (%note "foo"
- %case zddShow %of (tpl::GHCziShow.ZCTShow a)
- {GHCziShow.ZCDShow
- (tpl1::GHCziBase.Int ->
- a ->
- GHCziBase.ZMZN GHCziBase.Char -> GHCziBase.ZMZN GHCziBase.Cha
-r)
- (tpl2::a -> GHCziBase.ZMZN GHCziBase.Char)
- (tpl3::GHCziBase.ZMZN a ->
- GHCziBase.ZMZN GHCziBase.Char -> GHCziBase.ZMZN GHCziBase.Cha
-r) ->
- tpl2})
- (%note "bar"
- eta);
-</programlisting>
-
-<para>
- Here, we can see that the function <function>show</function> (which
- has been expanded out to a case expression over the Show dictionary)
- has a <literal>%note</literal> attached to it, as does the
- expression <varname>eta</varname> (which used to be called
- <varname>x</varname>).
-</para>
-
-</sect2>
-
</sect1>
<sect1 id="special-ids">
In particular:
<itemizedlist>
<listitem><para>
-<ulink url="&libraryGhcPrimLocation;/GHC-Exts.html#v%3Ainline"><literal>inline</literal></ulink>
+<ulink url="&libraryBaseLocation;/GHC-Exts.html#v%3Ainline"><literal>inline</literal></ulink>
allows control over inlining on a per-call-site basis.
</para></listitem>
<listitem><para>
-<ulink url="&libraryGhcPrimLocation;/GHC-Exts.html#v%3Alazy"><literal>lazy</literal></ulink>
+<ulink url="&libraryBaseLocation;/GHC-Exts.html#v%3Alazy"><literal>lazy</literal></ulink>
restrains the strictness analyser.
</para></listitem>
</itemizedlist>
url="http://www.seas.upenn.edu/~sweirich/papers/popl163af-weirich.pdf">Generative
type abstraction and type-level computation</ulink>, published at POPL 2011.</para>
-<sect2>
+<sect2 id="nominal-representational-and-phantom">
<title>Nominal, Representational, and Phantom</title>
<para>The goal of the roles system is to track when two types have the same
T Int Bool c</literal>).</para>
<para>GHC supports three different roles for type parameters: nominal,
-representational, and phantom. If a type parameter has a nominal (N) role,
-then the two types that differ must not actually differ at all: they must be
+representational, and phantom. If a type parameter has a nominal role, then
+the two types that differ must not actually differ at all: they must be
identical (after type family reduction). If a type parameter has a
-representational (R) role, then the two types must have the same
-representation. (If <literal>T</literal>'s first parameter's role is R, then
+representational role, then the two types must have the same representation.
+(If <literal>T</literal>'s first parameter's role is representational, then
<literal>T Age Bool c</literal> and <literal>T Int Bool c</literal> would have
-the same representation, because <literal>Age</literal> and <literal>Int</literal>
-have the same representation.) If a type parameter has a phantom (P) role,
-then we need no further information.</para>
+the same representation, because <literal>Age</literal> and
+<literal>Int</literal> have the same representation.) If a type parameter has
+a phantom role, then we need no further information.</para>
<para>Here are some examples:</para>
<programlisting>
- data Simple a = MkSimple a -- a has role R
+ data Simple a = MkSimple a -- a has role representational
type family F
type instance F Int = Bool
type instance F Age = Char
- data Complex a = MkComplex (F a) -- a has role N
+ data Complex a = MkComplex (F a) -- a has role nominal
- data Phant a = MkPhant Bool -- a has role P
+ data Phant a = MkPhant Bool -- a has role phantom
</programlisting>
-<para>The type <literal>Simple</literal> has its parameter at role R, which is
-generally the most common case. <literal>Simple Age</literal> would have the same
-representation as <literal>Simple Int</literal>. The type <literal>Complex</literal>,
-on the other hand, has its parameter at role N, because <literal>Simple Age</literal>
-and <literal>Simple Int</literal> are <emphasis>not</emphasis> the same. Lastly,
+<para>The type <literal>Simple</literal> has its parameter at role
+representational, which is generally the most common case. <literal>Simple
+Age</literal> would have the same representation as <literal>Simple
+Int</literal>. The type <literal>Complex</literal>, on the other hand, has its
+parameter at role nominal, because <literal>Simple Age</literal> and
+<literal>Simple Int</literal> are <emphasis>not</emphasis> the same. Lastly,
<literal>Phant Age</literal> and <literal>Phant Bool</literal> have the same
representation, even though <literal>Age</literal> and <literal>Bool</literal>
are unrelated.</para>
</sect2>
-<sect2>
+<sect2 id="role-inference">
<title>Role inference</title>
<para>
What role should a given type parameter should have? GHC performs role
inference to determine the correct role for every parameter. It starts with a
-few base facts: <literal>(->)</literal> has two R parameters;
-<literal>(~)</literal> has two N parameters; all type families' parameters are
-N; and all GADT-like parameters are N. Then, these facts are propagated to all
-places where these types are used. By defaulting parameters to role P, any
-parameters unused in the right-hand side (or used only in other types in P
-positions) will be P. Whenever a parameter is used in an R position (that is,
+few base facts: <literal>(->)</literal> has two representational parameters;
+<literal>(~)</literal> 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. 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 R), we raise its role from P to R. Similarly, when a parameter is used in
-an N position, its role is upgraded to N. We never downgrade a role from N to
-P or R, or from R to P. In this way, we infer the most-general role for each
-parameter.
+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.
+</para>
+
+<para>
+Classes have their roles default to nominal to promote coherence of class
+instances. If a <literal>C Int</literal> were stored in a datatype, it would
+be quite bad if that were somehow changed into a <literal>C Age</literal>
+somewhere, especially if another <literal>C Age</literal> had been declared!
</para>
<para>There is one particularly tricky case that should be explained:</para>
data Tricky a b = MkTricky (a b)
</programlisting>
-<para>What should <literal>Tricky</literal>'s roles be? At first blush, it would
-seem that both <literal>a</literal> and <literal>b</literal> should be at role R,
-since both are used in the right-hand side and neither is involved in a type family.
-However, this would be wrong, as the following example shows:</para>
+<para>What should <literal>Tricky</literal>'s roles be? At first blush, it
+would seem that both <literal>a</literal> and <literal>b</literal> should be
+at role representational, since both are used in the right-hand side and
+neither is involved in a type family. However, this would be wrong, as the
+following example shows:</para>
<programlisting>
data Nom a = MkNom (F a) -- type family F from example above
</programlisting>
<para>Is <literal>Tricky Nom Age</literal> representationally equal to
-<literal>Tricky Nom Int</literal>? No! The former stores a <literal>Char</literal>
-and the latter stores a <literal>Bool</literal>. The solution to this is
-to require all parameters to type variables to have role N. Thus, GHC would
-infer role R for <literal>a</literal> but role N for <literal>b</literal>.</para>
+<literal>Tricky Nom Int</literal>? No! The former stores a
+<literal>Char</literal> and the latter stores a <literal>Bool</literal>. The
+solution to this is to require all parameters to type variables to have role
+nominal. Thus, GHC would infer role representational for <literal>a</literal>
+but role nominal for <literal>b</literal>.</para>
</sect2>
-<sect2>
+<sect2 id="role-annotations">
<title>Role annotations
<indexterm><primary>-XRoleAnnotations</primary></indexterm>
</title>
</programlisting>
<para>
-The idea is that <literal>a</literal> should really be an R parameter, but
-role inference assigns it to P. This makes some level of sense: a pointer to
-an <literal>Int</literal> really is representationally the same as a pointer
-to a <literal>Bool</literal>. But, that's not at all how we want to use
-<literal>Ptr</literal>s! So, we want to be able to say</para>
+The idea is that <literal>a</literal> should really be a representational
+parameter, but role inference assigns it to phantom. This makes some level of
+sense: a pointer to an <literal>Int</literal> really is representationally the
+same as a pointer to a <literal>Bool</literal>. But, that's not at all how we
+want to use <literal>Ptr</literal>s! So, we want to be able to say</para>
<programlisting>
- data Ptr a@R = Ptr Addr#
+ type role Ptr representational
+ data Ptr a = Ptr Addr#
</programlisting>
<para>
-The <literal>@R</literal> (enabled with <option>-XRoleAnnotations</option>) annotation forces the
-parameter a to be at role R, not role P. GHC then checks
-the user-supplied roles to make sure they don't break any promises. It would
-be bad, for example, if the user could make <literal>BadIdea</literal>'s role be R.
+The <literal>type role</literal> (enabled with
+<option>-XRoleAnnotations</option>) declaration forces the parameter
+<literal>a</literal> to be at role representational, not role phantom. GHC
+then checks the user-supplied roles to make sure they don't break any
+promises. It would be bad, for example, if the user could make
+<literal>BadIdea</literal>'s role be representational.
</para>
<para>As another example, we can consider a type <literal>Set a</literal> that
represents a set of data, ordered according to <literal>a</literal>'s
<literal>Ord</literal> instance. While it would generally be type-safe to
-consider <literal>a</literal> to be at role R, it is possible that a
-<literal>newtype</literal> and its base type have
+consider <literal>a</literal> to be at role representational, it is possible
+that a <literal>newtype</literal> and its base type have
<emphasis>different</emphasis> orderings encoded in their respective
<literal>Ord</literal> instances. This would lead to misbehavior at runtime.
So, the author of the <literal>Set</literal> datatype would like its parameter
-to be at role N. This would be done with a declaration</para>
+to be at role nominal. This would be done with a declaration</para>
<programlisting>
- data Set a@N = ...
+ type role Set nominal
</programlisting>
+<para>Role annotations can also be used should a programmer wish to write
+a class with a representational (or phantom) role. However, as a class
+with non-nominal roles can quickly lead to class instance incoherence,
+it is necessary to also specify <option>-XIncoherentInstances</option>
+to allow non-nominal roles for classes.</para>
+
<para>The other place where role annotations may be necessary are in
<literal>hs-boot</literal> files (<xref linkend="mutual-recursion"/>), where
the right-hand sides of definitions can be omitted. As usual, the
types/classes declared in an <literal>hs-boot</literal> file must match up
with the definitions in the <literal>hs</literal> file, including down to the
-roles. The default role is R in <literal>hs-boot</literal> files,
+roles. The default role for datatypes
+is representational in <literal>hs-boot</literal> files,
corresponding to the common use case.</para>
<para>
-Role annotations are allowed on type variables in data, newtype, class,
-and type declarations. They are not allowed on type/data family
-declarations or in explicit foralls in function type signatures.
-The syntax for a role annotation is an <literal>@</literal> sign followed
-by one of <literal>N</literal>, <literal>R</literal>, or <literal>P</literal>,
-directly following a type variable. If the type variable has an explicit
-kind annotation, the role annotation goes after the kind annotation, outside
-the parentheses. Here are some examples:</para>
+Role annotations are allowed on data, newtype, and class declarations. A role
+annotation declaration starts with <literal>type role</literal> and is
+followed by one role listing for each parameter of the type. (This parameter
+count includes parameters implicitly specified by a kind signature in a
+GADT-style data or newtype declaration.) Each role listing is a role
+(<literal>nominal</literal>, <literal>representational</literal>, or
+<literal>phantom</literal>) or a <literal>_</literal>. Using a
+<literal>_</literal> says that GHC should infer that role. The role annotation
+may go anywhere in the same module as the datatype or class definition
+(much like a value-level type signature).
+Here are some examples:</para>
<programlisting>
- data T1 a b@P = MkT1 a -- b is not used; annotation is fine but unnecessary
- data T2 a b@P = MkT2 b -- ERROR: b is used and cannot be P
- data T3 a b@N = MkT3 a -- OK: N is higher than necessary, but safe
- data T4 (a :: * -> *)@N = MkT4 (a Int) -- OK, but N is higher than necessary
- class C a@R b where ... -- OK
- type X a@N = ... -- OK
- type family F a@R -- ERROR: annotations not allowed on family declarations
+ type role T1 _ phantom
+ data T1 a b = MkT1 a -- b is not used; annotation is fine but unnecessary
+
+ type role T2 _ phantom
+ data T2 a b = MkT2 b -- ERROR: b is used and cannot be phantom
+
+ type role T3 _ nominal
+ 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 nominal is higher than necessary
+
+ type role C representational _ -- OK, with -XIncoherentInstances
+ 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
</programlisting>
</sect2>