allows you to define postfix operators. The extension is this: the left section
<programlisting>
(e !)
-</programlisting>
+</programlisting>
is equivalent (from the point of view of both type checking and execution) to the expression
<programlisting>
((!) e)
-</programlisting>
+</programlisting>
(for any expression <literal>e</literal> and operator <literal>(!)</literal>.
The strict Haskell 98 interpretation is that the section is equivalent to
<programlisting>
(\y -> (!) e y)
-</programlisting>
+</programlisting>
That is, the operator must be a function of two arguments. GHC allows it to
take only one argument, and that in turn allows you to write the function
postfix.
</sect3>
-<sect3>
-<title>Type classes</title>
+<sect3 id="existential-with-context">
+<title>Existentials and type classes</title>
<para>
An easy extension is to allow
extract it on pattern matching.
</para>
-<para>
-Notice the way that the syntax fits smoothly with that used for
-universal quantification earlier.
-</para>
-
</sect3>
<sect3 id="existential-records">
generated by the call to <literal>elem</literal>, so that the type of
<literal>insert</literal> itself has no <literal>Eq</literal> constraint.
</para>
-<para>This behaviour contrasts with Haskell 98's peculiar treatment of
-contexts on a data type declaration (Section 4.2.1 of the Haskell 98 Report).
-In Haskell 98 the definition
-<programlisting>
- data Eq a => Set' a = MkSet' [a]
-</programlisting>
-gives <literal>MkSet'</literal> the same type as <literal>MkSet</literal> above. But instead of
-<emphasis>making available</emphasis> an <literal>(Eq a)</literal> constraint, pattern-matching
-on <literal>MkSet'</literal> <emphasis>requires</emphasis> an <literal>(Eq a)</literal> constraint!
-GHC faithfully implements this behaviour, odd though it is. But for GADT-style declarations,
-GHC's behaviour is much more useful, as well as much more intuitive.</para>
<para>
-For example, a possible application of GHC's behaviour is to reify dictionaries:
+For example, one possible application is to reify dictionaries:
<programlisting>
data NumInst a where
MkNumInst :: Num a => NumInst a
Here, a value of type <literal>NumInst a</literal> is equivalent
to an explicit <literal>(Num a)</literal> dictionary.
</para>
+<para>
+All this applies to constructors declared using the syntax of <xref linkend="existential-with-context"/>.
+For example, the <literal>NumInst</literal> data type above could equivalently be declared
+like this:
+<programlisting>
+ data NumInst a
+ = Num a => MkNumInst (NumInst a)
+</programlisting>
+Notice that, unlike the situation when declaring an existental, there is
+no <literal>forall</literal>, because the <literal>Num</literal> constrains the
+data type's univerally quantified type variable <literal>a</literal>.
+A constructor may have both universal and existential type variables: for example,
+the following two declarations are equivalent:
+<programlisting>
+ data T1 a
+ = forall b. (Num a, Eq b) => MkT1 a b
+ data T2 a where
+ MkT2 :: (Num a, Eq b) => a -> b -> T2 a
+</programlisting>
+</para>
+<para>All this behaviour contrasts with Haskell 98's peculiar treatment of
+contexts on a data type declaration (Section 4.2.1 of the Haskell 98 Report).
+In Haskell 98 the definition
+<programlisting>
+ data Eq a => Set' a = MkSet' [a]
+</programlisting>
+gives <literal>MkSet'</literal> the same type as <literal>MkSet</literal> above. But instead of
+<emphasis>making available</emphasis> an <literal>(Eq a)</literal> constraint, pattern-matching
+on <literal>MkSet'</literal> <emphasis>requires</emphasis> an <literal>(Eq a)</literal> constraint!
+GHC faithfully implements this behaviour, odd though it is. But for GADT-style declarations,
+GHC's behaviour is much more useful, as well as much more intuitive.
+</para>
<para>
The rest of this section gives further details about GADT-style data
other classes you have to write an explicit instance declaration. For
example, if you define
-<programlisting>
+<programlisting>
newtype Dollars = Dollars Int
-</programlisting>
+</programlisting>
and you want to use arithmetic on <literal>Dollars</literal>, you have to
explicitly define an instance of <literal>Num</literal>:
-<programlisting>
+<programlisting>
instance Num Dollars where
Dollars a + Dollars b = Dollars (a+b)
...
GHC now permits such instances to be derived instead,
using the flag <option>-XGeneralizedNewtypeDeriving</option>,
so one can write
-<programlisting>
+<programlisting>
newtype Dollars = Dollars Int deriving (Eq,Show,Num)
-</programlisting>
+</programlisting>
and the implementation uses the <emphasis>same</emphasis> <literal>Num</literal> dictionary
for <literal>Dollars</literal> as for <literal>Int</literal>. Notionally, the compiler
derives an instance declaration of the form
-<programlisting>
+<programlisting>
instance Num Int => Num Dollars
-</programlisting>
+</programlisting>
which just adds or removes the <literal>newtype</literal> constructor according to the type.
</para>
way. For example, suppose we have implemented state and failure monad
transformers, such that
-<programlisting>
+<programlisting>
instance Monad m => Monad (State s m)
instance Monad m => Monad (Failure m)
-</programlisting>
+</programlisting>
In Haskell 98, we can define a parsing monad by
-<programlisting>
+<programlisting>
type Parser tok m a = State [tok] (Failure m) a
-</programlisting>
+</programlisting>
which is automatically a monad thanks to the instance declarations
above. With the extension, we can make the parser type abstract,
without needing to write an instance of class <literal>Monad</literal>, via
-<programlisting>
+<programlisting>
newtype Parser tok m a = Parser (State [tok] (Failure m) a)
deriving Monad
</programlisting>
In this case the derived instance declaration is of the form
-<programlisting>
+<programlisting>
instance Monad (State [tok] (Failure m)) => Monad (Parser tok m)
-</programlisting>
+</programlisting>
Notice that, since <literal>Monad</literal> is a constructor class, the
instance is a <emphasis>partial application</emphasis> of the new type, not the
application'' of the class appears in the <literal>deriving</literal>
clause. For example, given the class
-<programlisting>
+<programlisting>
class StateMonad s m | m -> s where ...
instance Monad m => StateMonad s (State s m) where ...
-</programlisting>
+</programlisting>
then we can derive an instance of <literal>StateMonad</literal> for <literal>Parser</literal>s by
-<programlisting>
+<programlisting>
newtype Parser tok m a = Parser (State [tok] (Failure m) a)
deriving (Monad, StateMonad [tok])
</programlisting>
The derived instance is obtained by completing the application of the
class to the new type:
-<programlisting>
+<programlisting>
instance StateMonad [tok] (State [tok] (Failure m)) =>
StateMonad [tok] (Parser tok m)
</programlisting>
Derived instance declarations are constructed as follows. Consider the
declaration (after expansion of any type synonyms)
-<programlisting>
+<programlisting>
newtype T v1...vn = T' (t vk+1...vn) deriving (c1...cm)
-</programlisting>
+</programlisting>
where
<itemizedlist>
</itemizedlist>
Then, for each <literal>ci</literal>, the derived instance
declaration is:
-<programlisting>
+<programlisting>
instance ci t => ci (T v1...vk)
</programlisting>
As an example which does <emphasis>not</emphasis> work, consider
-<programlisting>
+<programlisting>
newtype NonMonad m s = NonMonad (State s m s) deriving Monad
-</programlisting>
+</programlisting>
Here we cannot derive the instance
-<programlisting>
+<programlisting>
instance Monad (State s m) => Monad (NonMonad m)
-</programlisting>
+</programlisting>
because the type variable <literal>s</literal> occurs in <literal>State s m</literal>,
and so cannot be "eta-converted" away. It is a good thing that this
important, since we can only derive instances for the last one. If the
<literal>StateMonad</literal> class above were instead defined as
-<programlisting>
+<programlisting>
class StateMonad m s | m -> s where ...
</programlisting>
The type of <literal>elem</literal> is illegal in Haskell 98, because it
contains the constraint <literal>Eq a</literal>, constrains only the
class type variable (in this case <literal>a</literal>).
-GHC lifts this restriction.
+GHC lifts this restriction (flag <option>-XConstrainedClassMethods</option>).
</para>
is a type variable that occurs in the head.
</para>
<para>
-The <option>-fglasgow-exts</option> flag loosens these restrictions
+The <option>-XFlexibleInstances</option> flag loosens these restrictions
considerably. Firstly, multi-parameter type classes are permitted. Secondly,
the context and head of the instance declaration can each consist of arbitrary
(well-kinded) assertions <literal>(C t1 ... tn)</literal> subject only to the
class F a b | a->b
instance F [a] [[a]]
instance (D c, F a c) => D [a] -- 'c' is not mentioned in the head
-</programlisting>
+</programlisting>
Similarly, it can be tempting to lift the coverage condition:
<programlisting>
class Mul a b c | a b -> c where
<sect2 id="type-restrictions">
<title>Type signatures</title>
-<sect3><title>The context of a type signature</title>
+<sect3 id="flexible-contexts"><title>The context of a type signature</title>
<para>
Unlike Haskell 98, constraints in types do <emphasis>not</emphasis> have to be of
the form <emphasis>(class type-variable)</emphasis> or
it has rank-2 types on the left of a function arrow.
</para>
<para>
-GHC allows types of arbitrary rank; you can nest <literal>forall</literal>s
-arbitrarily deep in function arrows. (GHC used to be restricted to rank 2, but
-that restriction has now been lifted.)
+GHC has three flags to control higher-rank types:
+<itemizedlist>
+<listitem><para>
+ <option>-XPolymorphicComponents</option>: data constructors (only) can have polymorphic argment types.
+</para></listitem>
+<listitem><para>
+ <option>-XRank2Types</option>: any function (including data constructors) can have a rank-2 type.
+</para></listitem>
+<listitem><para>
+ <option>-XRankNTypes</option>: any function (including data constructors) can have an arbitrary-rank type.
+That is, you can nest <literal>forall</literal>s
+arbitrarily deep in function arrows.
In particular, a forall-type (also called a "type scheme"),
including an operational type class context, is legal:
<itemizedlist>
<listitem> <para> As the type of an implicit parameter </para> </listitem>
<listitem> <para> In a pattern type signature (see <xref linkend="scoped-type-variables"/>) </para> </listitem>
</itemizedlist>
+</para></listitem>
+</itemizedlist>
Of course <literal>forall</literal> becomes a keyword; you can't use <literal>forall</literal> as
a type variable any more!
</para>
<title>Pattern type signatures</title>
<para>
A type signature may occur in any pattern; this is a <emphasis>pattern type
-signature</emphasis>.
+signature</emphasis>.
For example:
<programlisting>
-- f and g assume that 'a' is already in scope
signature simply constrains the type of the pattern in the obvious way.
</para>
<para>
-There is only one situation in which you can write a pattern type signature that
-mentions a type variable that is not already in scope, namely in pattern match
-of an existential data constructor. For example:
+Unlike expression and declaration type signatures, pattern type signatures are not implictly generalised.
+The pattern in a <emphasis>patterm binding</emphasis> may only mention type variables
+that are already in scope. For example:
+<programlisting>
+ f :: forall a. [a] -> (Int, [a])
+ f xs = (n, zs)
+ where
+ (ys::[a], n) = (reverse xs, length xs) -- OK
+ zs::[a] = xs ++ ys -- OK
+
+ Just (v::b) = ... -- Not OK; b is not in scope
+</programlisting>
+Here, the pattern signatures for <literal>ys</literal> and <literal>zs</literal>
+are fine, but the one for <literal>v</literal> is not because <literal>b</literal> is
+not in scope.
+</para>
+<para>
+However, in all patterns <emphasis>other</emphasis> than pattern bindings, a pattern
+type signature may mention a type variable that is not in scope; in this case,
+<emphasis>the signature brings that type variable into scope</emphasis>.
+This is particularly important for existential data constructors. For example:
<programlisting>
data T = forall a. MkT [a]
t3::[a] = [t,t,t]
</programlisting>
Here, the pattern type signature <literal>(t::a)</literal> mentions a lexical type
-variable that is not already in scope. Indeed, it cannot already be in scope,
+variable that is not already in scope. Indeed, it <emphasis>cannot</emphasis> already be in scope,
because it is bound by the pattern match. GHC's rule is that in this situation
(and only then), a pattern type signature can mention a type variable that is
not already in scope; the effect is to bring it into scope, standing for the
existentially-bound type variable.
</para>
<para>
-If this seems a little odd, we think so too. But we must have
+When a pattern type signature binds a type variable in this way, GHC insists that the
+type variable is bound to a <emphasis>rigid</emphasis>, or fully-known, type variable.
+This means that any user-written type signature always stands for a completely known type.
+</para>
+<para>
+If all this seems a little odd, we think so too. But we must have
<emphasis>some</emphasis> way to bring such type variables into scope, else we
could not name existentially-bound type variables in subsequent type signatures.
</para>
<para>The major effect of an <literal>INLINE</literal> pragma
is to declare a function's “cost” to be very low.
The normal unfolding machinery will then be very keen to
- inline it.</para>
-
+ inline it. However, an <literal>INLINE</literal> pragma for a
+ function "<literal>f</literal>" has a number of other effects:
+<itemizedlist>
+<listitem><para>
+No funtions are inlined into <literal>f</literal>. Otherwise
+GHC might inline a big function into <literal>f</literal>'s right hand side,
+making <literal>f</literal> big; and then inline <literal>f</literal> blindly.
+</para></listitem>
+<listitem><para>
+The float-in, float-out, and common-sub-expression transformations are not
+applied to the body of <literal>f</literal>.
+</para></listitem>
+<listitem><para>
+An INLINE function is not worker/wrappered by strictness analysis.
+It's going to be inlined wholesale instead.
+</para></listitem>
+</itemizedlist>
+All of these effects are aimed at ensuring that what gets inlined is
+exactly what you asked for, no more and no less.
+</para>
<para>Syntactically, an <literal>INLINE</literal> pragma for a
function can be put anywhere its type signature could be
put.</para>
h :: Eq a => a -> a -> a
{-# SPECIALISE h :: (Eq a) => [a] -> [a] -> [a] #-}
-</programlisting>
+</programlisting>
The last of these examples will generate a
RULE with a somewhat-complex left-hand side (try it yourself), so it might not fire very
well. If you use this kind of specialisation, let us know how well it works.
[x] = e -- A pattern binding
</programlisting>
Experimentally, GHC now makes pattern bindings monomorphic <emphasis>by
-default</emphasis>. Use <option>-XMonoPatBinds</option> to recover the
+default</emphasis>. Use <option>-XNoMonoPatBinds</option> to recover the
standard behaviour.
</para>
</sect2>