</varlistentry>
<varlistentry>
+ <term><option>-foverloaded-strings</option></term>
+ <listitem>
+ <para>Enables overloaded string literals (see <xref
+ linkend="overloaded-strings"/>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-fscoped-type-variables</option></term>
<listitem>
<para>Enables lexically-scoped type variables (see <xref
</para>
<programlisting>
-clunky env var1 var1 = case lookup env var1 of
+clunky env var1 var2 = case lookup env var1 of
Nothing -> fail
Just val1 -> case lookup env var2 of
Nothing -> fail
</para>
<programlisting>
-clunky env var1 var1
+clunky env var1 var2
| Just val1 <- lookup env var1
, Just val2 <- lookup env var2
= val1 + val2
<!-- TYPE SYSTEM EXTENSIONS -->
-<sect1 id="type-extensions">
-<title>Type system extensions</title>
-
-
-<sect2>
-<title>Data types and type synonyms</title>
+<sect1 id="data-type-extensions">
+<title>Extensions to data types and type synonyms</title>
-<sect3 id="nullary-types">
+<sect2 id="nullary-types">
<title>Data types with no constructors</title>
<para>With the <option>-fglasgow-exts</option> flag, GHC lets you declare
<para>Syntactically, the declaration lacks the "= constrs" part. The
type can be parameterised over types of any kind, but if the kind is
not <literal>*</literal> then an explicit kind annotation must be used
-(see <xref linkend="sec-kinding"/>).</para>
+(see <xref linkend="kinding"/>).</para>
<para>Such data types have only one value, namely bottom.
Nevertheless, they can be useful when defining "phantom types".</para>
-</sect3>
+</sect2>
-<sect3 id="infix-tycons">
+<sect2 id="infix-tycons">
<title>Infix type constructors, classes, and type variables</title>
<para>
</itemizedlist>
</para>
-</sect3>
+</sect2>
-<sect3 id="type-synonyms">
+<sect2 id="type-synonyms">
<title>Liberalised type synonyms</title>
<para>
</programlisting>
because GHC does not allow unboxed tuples on the left of a function arrow.
</para>
-</sect3>
+</sect2>
-<sect3 id="existential-quantification">
+<sect2 id="existential-quantification">
<title>Existentially quantified data constructors
</title>
quite a bit of object-oriented-like programming this way.
</para>
-<sect4 id="existential">
+<sect3 id="existential">
<title>Why existential?
</title>
adding a new existential quantification construct.
</para>
-</sect4>
+</sect3>
-<sect4>
+<sect3>
<title>Type classes</title>
<para>
universal quantification earlier.
</para>
-</sect4>
+</sect3>
-<sect4 id="existential-records">
+<sect3 id="existential-records">
<title>Record Constructors</title>
<para>
Here <literal>tag</literal> is a public field, with a well-typed selector
function <literal>tag :: Counter a -> a</literal>. The <literal>self</literal>
type is hidden from the outside; any attempt to apply <literal>_this</literal>,
-<literal>_inc</literal> or <literal>_output</literal> as functions will raise a
+<literal>_inc</literal> or <literal>_display</literal> as functions will raise a
compile-time error. In other words, <emphasis>GHC defines a record selector function
only for fields whose type does not mention the existentially-quantified variables</emphasis>.
(This example used an underscore in the fields for which record selectors
</para>
-</sect4>
+</sect3>
-<sect4>
+<sect3>
<title>Restrictions</title>
<para>
</para>
-</sect4>
</sect3>
+</sect2>
<!-- ====================== Generalised algebraic data types ======================= -->
-<sect3 id="gadt-style">
+<sect2 id="gadt-style">
<title>Declaring data types with explicit constructor signatures</title>
<para>GHC allows you to declare an algebraic data type by
Nevertheless, you can still use all the field names in pattern matching and record construction.
</para></listitem>
</itemizedlist></para>
-</sect3>
+</sect2>
-<sect3 id="gadt">
+<sect2 id="gadt">
<title>Generalised Algebraic Data Types (GADTs)</title>
<para>Generalised Algebraic Data Types generalise ordinary algebraic data types
</itemizedlist>
</para>
-</sect3>
-
-<!-- ====================== End of Generalised algebraic data types ======================= -->
-
-
</sect2>
+<!-- ====================== End of Generalised algebraic data types ======================= -->
-<sect2 id="multi-param-type-classes">
-<title>Class declarations</title>
+<sect2 id="deriving-typeable">
+<title>Deriving clause for classes <literal>Typeable</literal> and <literal>Data</literal></title>
<para>
-This section, and the next one, documents GHC's type-class extensions.
-There's lots of background in the paper <ulink
-url="http://research.microsoft.com/~simonpj/Papers/type-class-design-space" >Type
-classes: exploring the design space</ulink > (Simon Peyton Jones, Mark
-Jones, Erik Meijer).
+Haskell 98 allows the programmer to add "<literal>deriving( Eq, Ord )</literal>" to a data type
+declaration, to generate a standard instance declaration for classes specified in the <literal>deriving</literal> clause.
+In Haskell 98, the only classes that may appear in the <literal>deriving</literal> clause are the standard
+classes <literal>Eq</literal>, <literal>Ord</literal>,
+<literal>Enum</literal>, <literal>Ix</literal>, <literal>Bounded</literal>, <literal>Read</literal>, and <literal>Show</literal>.
</para>
<para>
-All the extensions are enabled by the <option>-fglasgow-exts</option> flag.
+GHC extends this list with two more classes that may be automatically derived
+(provided the <option>-fglasgow-exts</option> flag is specified):
+<literal>Typeable</literal>, and <literal>Data</literal>. These classes are defined in the library
+modules <literal>Data.Typeable</literal> and <literal>Data.Generics</literal> respectively, and the
+appropriate class must be in scope before it can be mentioned in the <literal>deriving</literal> clause.
</para>
-
-<sect3>
-<title>Multi-parameter type classes</title>
-<para>
-Multi-parameter type classes are permitted. For example:
-
-
-<programlisting>
- class Collection c a where
- union :: c a -> c a -> c a
- ...etc.
-</programlisting>
-
+<para>An instance of <literal>Typeable</literal> can only be derived if the
+data type has seven or fewer type parameters, all of kind <literal>*</literal>.
+The reason for this is that the <literal>Typeable</literal> class is derived using the scheme
+described in
+<ulink url="http://research.microsoft.com/%7Esimonpj/papers/hmap/gmap2.ps">
+Scrap More Boilerplate: Reflection, Zips, and Generalised Casts
+</ulink>.
+(Section 7.4 of the paper describes the multiple <literal>Typeable</literal> classes that
+are used, and only <literal>Typeable1</literal> up to
+<literal>Typeable7</literal> are provided in the library.)
+In other cases, there is nothing to stop the programmer writing a <literal>TypableX</literal>
+class, whose kind suits that of the data type constructor, and
+then writing the data type instance by hand.
</para>
-</sect3>
+</sect2>
-<sect3>
-<title>The superclasses of a class declaration</title>
+<sect2 id="newtype-deriving">
+<title>Generalised derived instances for newtypes</title>
<para>
-There are no restrictions on the context in a class declaration
-(which introduces superclasses), except that the class hierarchy must
-be acyclic. So these class declarations are OK:
+When you define an abstract type using <literal>newtype</literal>, you may want
+the new type to inherit some instances from its representation. In
+Haskell 98, you can inherit instances of <literal>Eq</literal>, <literal>Ord</literal>,
+<literal>Enum</literal> and <literal>Bounded</literal> by deriving them, but for any
+other classes you have to write an explicit instance declaration. For
+example, if you define
+
+<programlisting>
+ newtype Dollars = Dollars Int
+</programlisting>
+and you want to use arithmetic on <literal>Dollars</literal>, you have to
+explicitly define an instance of <literal>Num</literal>:
-<programlisting>
- class Functor (m k) => FiniteMap m k where
+<programlisting>
+ instance Num Dollars where
+ Dollars a + Dollars b = Dollars (a+b)
...
-
- class (Monad m, Monad (t m)) => Transform t m where
- lift :: m a -> (t m) a
</programlisting>
-
-
+All the instance does is apply and remove the <literal>newtype</literal>
+constructor. It is particularly galling that, since the constructor
+doesn't appear at run-time, this instance declaration defines a
+dictionary which is <emphasis>wholly equivalent</emphasis> to the <literal>Int</literal>
+dictionary, only slower!
</para>
-<para>
-As in Haskell 98, The class hierarchy must be acyclic. However, the definition
-of "acyclic" involves only the superclass relationships. For example,
-this is OK:
-<programlisting>
- class C a where {
- op :: D b => a -> b -> b
- }
+<sect3> <title> Generalising the deriving clause </title>
+<para>
+GHC now permits such instances to be derived instead, so one can write
+<programlisting>
+ newtype Dollars = Dollars Int deriving (Eq,Show,Num)
+</programlisting>
- class C a => D a where { ... }
-</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>
+ instance Num Int => Num Dollars
+</programlisting>
-Here, <literal>C</literal> is a superclass of <literal>D</literal>, but it's OK for a
-class operation <literal>op</literal> of <literal>C</literal> to mention <literal>D</literal>. (It
-would not be OK for <literal>D</literal> to be a superclass of <literal>C</literal>.)
+which just adds or removes the <literal>newtype</literal> constructor according to the type.
</para>
-</sect3>
-
+<para>
+We can also derive instances of constructor classes in a similar
+way. For example, suppose we have implemented state and failure monad
+transformers, such that
+<programlisting>
+ instance Monad m => Monad (State s m)
+ instance Monad m => Monad (Failure m)
+</programlisting>
+In Haskell 98, we can define a parsing monad by
+<programlisting>
+ type Parser tok m a = State [tok] (Failure m) a
+</programlisting>
-<sect3 id="class-method-types">
-<title>Class method types</title>
+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
-<para>
-Haskell 98 prohibits class method types to mention constraints on the
-class type variable, thus:
-<programlisting>
- class Seq s a where
- fromList :: [a] -> s a
- elem :: Eq a => a -> s a -> Bool
+<programlisting>
+ newtype Parser tok m a = Parser (State [tok] (Failure m) a)
+ deriving Monad
</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.
+In this case the derived instance declaration is of the form
+<programlisting>
+ instance Monad (State [tok] (Failure m)) => Monad (Parser tok m)
+</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
+entire left hand side. We can imagine that the type declaration is
+``eta-converted'' to generate the context of the instance
+declaration.
</para>
+<para>
+We can even derive instances of multi-parameter classes, provided the
+newtype is the last class parameter. In this case, a ``partial
+application'' of the class appears in the <literal>deriving</literal>
+clause. For example, given the class
-</sect3>
-</sect2>
+<programlisting>
+ class StateMonad s m | m -> s where ...
+ instance Monad m => StateMonad s (State s m) where ...
+</programlisting>
+then we can derive an instance of <literal>StateMonad</literal> for <literal>Parser</literal>s by
+<programlisting>
+ newtype Parser tok m a = Parser (State [tok] (Failure m) a)
+ deriving (Monad, StateMonad [tok])
+</programlisting>
-<sect2 id="functional-dependencies">
-<title>Functional dependencies
-</title>
+The derived instance is obtained by completing the application of the
+class to the new type:
-<para> Functional dependencies are implemented as described by Mark Jones
-in “<ulink url="http://www.cse.ogi.edu/~mpj/pubs/fundeps.html">Type Classes with Functional Dependencies</ulink>”, Mark P. Jones,
-In Proceedings of the 9th European Symposium on Programming,
-ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782,
-.
+<programlisting>
+ instance StateMonad [tok] (State [tok] (Failure m)) =>
+ StateMonad [tok] (Parser tok m)
+</programlisting>
</para>
<para>
-Functional dependencies are introduced by a vertical bar in the syntax of a
-class declaration; e.g.
-<programlisting>
- class (Monad m) => MonadState s m | m -> s where ...
- class Foo a b c | a b -> c where ...
-</programlisting>
-There should be more documentation, but there isn't (yet). Yell if you need it.
+As a result of this extension, all derived instances in newtype
+ declarations are treated uniformly (and implemented just by reusing
+the dictionary for the representation type), <emphasis>except</emphasis>
+<literal>Show</literal> and <literal>Read</literal>, which really behave differently for
+the newtype and its representation.
</para>
+</sect3>
-<sect3><title>Rules for functional dependencies </title>
+<sect3> <title> A more precise specification </title>
<para>
-In a class declaration, all of the class type variables must be reachable (in the sense
-mentioned in <xref linkend="type-restrictions"/>)
-from the free variables of each method type.
-For example:
-
-<programlisting>
- class Coll s a where
- empty :: s
- insert :: s -> a -> s
-</programlisting>
-
-is not OK, because the type of <literal>empty</literal> doesn't mention
-<literal>a</literal>. Functional dependencies can make the type variable
-reachable:
-<programlisting>
- class Coll s a | s -> a where
- empty :: s
- insert :: s -> a -> s
-</programlisting>
+Derived instance declarations are constructed as follows. Consider the
+declaration (after expansion of any type synonyms)
-Alternatively <literal>Coll</literal> might be rewritten
+<programlisting>
+ newtype T v1...vn = T' (t vk+1...vn) deriving (c1...cm)
+</programlisting>
-<programlisting>
- class Coll s a where
- empty :: s a
+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>
+ 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.
+</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
+</para></listitem>
+<listitem><para>
+ None of the <literal>ci</literal> is <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>
+</itemizedlist>
+Then, for each <literal>ci</literal>, the derived instance
+declaration is:
+<programlisting>
+ instance ci t => ci (T v1...vk)
+</programlisting>
+As an example which does <emphasis>not</emphasis> work, consider
+<programlisting>
+ newtype NonMonad m s = NonMonad (State s m s) deriving Monad
+</programlisting>
+Here we cannot derive the instance
+<programlisting>
+ instance Monad (State s m) => Monad (NonMonad m)
+</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
+<literal>deriving</literal> clause is rejected, because <literal>NonMonad m</literal> is
+not, in fact, a monad --- for the same reason. Try defining
+<literal>>>=</literal> with the correct type: you won't be able to.
+</para>
+<para>
+
+Notice also that the <emphasis>order</emphasis> of class parameters becomes
+important, since we can only derive instances for the last one. If the
+<literal>StateMonad</literal> class above were instead defined as
+
+<programlisting>
+ class StateMonad m s | m -> s where ...
+</programlisting>
+
+then we would not have been able to derive an instance for the
+<literal>Parser</literal> type above. We hypothesise that multi-parameter
+classes usually have one "main" parameter for which deriving new
+instances is most interesting.
+</para>
+<para>Lastly, all of this applies only for classes other than
+<literal>Read</literal>, <literal>Show</literal>, <literal>Typeable</literal>,
+and <literal>Data</literal>, for which the built-in derivation applies (section
+4.3.3. of the Haskell Report).
+(For the standard classes <literal>Eq</literal>, <literal>Ord</literal>,
+<literal>Ix</literal>, and <literal>Bounded</literal> it is immaterial whether
+the standard method is used or the one described here.)
+</para>
+</sect3>
+
+</sect2>
+
+<sect2 id="stand-alone-deriving">
+<title>Stand-alone deriving declarations</title>
+
+<para>
+GHC now allows stand-alone <literal>deriving</literal> declarations, enabled by <literal>-fglasgow-exts</literal>:
+<programlisting>
+ data Foo a = Bar a | Baz String
+
+ derive instance Eq (Foo a)
+</programlisting>
+The token "<literal>derive</literal>" is a keyword only when followed by "<literal>instance</literal>";
+you can use it as a variable name elsewhere.</para>
+<para>The stand-alone syntax is generalised for newtypes in exactly the same
+way that ordinary <literal>deriving</literal> clauses are generalised (<xref linkend="newtype-deriving"/>).
+For example:
+<programlisting>
+ newtype Foo a = MkFoo (State Int a)
+
+ derive instance MonadState Int Foo
+</programlisting>
+GHC always treats the <emphasis>last</emphasis> parameter of the instance
+(<literal>Foo</literal> in this exmample) as the type whose instance is being derived.
+</para>
+
+</sect2>
+
+</sect1>
+
+
+<!-- TYPE SYSTEM EXTENSIONS -->
+<sect1 id="other-type-extensions">
+<title>Other type system extensions</title>
+
+<sect2 id="multi-param-type-classes">
+<title>Class declarations</title>
+
+<para>
+This section, and the next one, documents GHC's type-class extensions.
+There's lots of background in the paper <ulink
+url="http://research.microsoft.com/~simonpj/Papers/type-class-design-space" >Type
+classes: exploring the design space</ulink > (Simon Peyton Jones, Mark
+Jones, Erik Meijer).
+</para>
+<para>
+All the extensions are enabled by the <option>-fglasgow-exts</option> flag.
+</para>
+
+<sect3>
+<title>Multi-parameter type classes</title>
+<para>
+Multi-parameter type classes are permitted. For example:
+
+
+<programlisting>
+ class Collection c a where
+ union :: c a -> c a -> c a
+ ...etc.
+</programlisting>
+
+</para>
+</sect3>
+
+<sect3>
+<title>The superclasses of a class declaration</title>
+
+<para>
+There are no restrictions on the context in a class declaration
+(which introduces superclasses), except that the class hierarchy must
+be acyclic. So these class declarations are OK:
+
+
+<programlisting>
+ class Functor (m k) => FiniteMap m k where
+ ...
+
+ class (Monad m, Monad (t m)) => Transform t m where
+ lift :: m a -> (t m) a
+</programlisting>
+
+
+</para>
+<para>
+As in Haskell 98, The class hierarchy must be acyclic. However, the definition
+of "acyclic" involves only the superclass relationships. For example,
+this is OK:
+
+
+<programlisting>
+ class C a where {
+ op :: D b => a -> b -> b
+ }
+
+ class C a => D a where { ... }
+</programlisting>
+
+
+Here, <literal>C</literal> is a superclass of <literal>D</literal>, but it's OK for a
+class operation <literal>op</literal> of <literal>C</literal> to mention <literal>D</literal>. (It
+would not be OK for <literal>D</literal> to be a superclass of <literal>C</literal>.)
+</para>
+</sect3>
+
+
+
+
+<sect3 id="class-method-types">
+<title>Class method types</title>
+
+<para>
+Haskell 98 prohibits class method types to mention constraints on the
+class type variable, thus:
+<programlisting>
+ class Seq s a where
+ fromList :: [a] -> s a
+ elem :: Eq a => a -> s a -> Bool
+</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.
+</para>
+
+
+</sect3>
+</sect2>
+
+<sect2 id="functional-dependencies">
+<title>Functional dependencies
+</title>
+
+<para> Functional dependencies are implemented as described by Mark Jones
+in “<ulink url="http://www.cse.ogi.edu/~mpj/pubs/fundeps.html">Type Classes with Functional Dependencies</ulink>”, Mark P. Jones,
+In Proceedings of the 9th European Symposium on Programming,
+ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782,
+.
+</para>
+<para>
+Functional dependencies are introduced by a vertical bar in the syntax of a
+class declaration; e.g.
+<programlisting>
+ class (Monad m) => MonadState s m | m -> s where ...
+
+ class Foo a b c | a b -> c where ...
+</programlisting>
+There should be more documentation, but there isn't (yet). Yell if you need it.
+</para>
+
+<sect3><title>Rules for functional dependencies </title>
+<para>
+In a class declaration, all of the class type variables must be reachable (in the sense
+mentioned in <xref linkend="type-restrictions"/>)
+from the free variables of each method type.
+For example:
+
+<programlisting>
+ class Coll s a where
+ empty :: s
+ insert :: s -> a -> s
+</programlisting>
+
+is not OK, because the type of <literal>empty</literal> doesn't mention
+<literal>a</literal>. Functional dependencies can make the type variable
+reachable:
+<programlisting>
+ class Coll s a | s -> a where
+ empty :: s
+ insert :: s -> a -> s
+</programlisting>
+
+Alternatively <literal>Coll</literal> might be rewritten
+
+<programlisting>
+ class Coll s a where
+ empty :: s a
insert :: s a -> a -> s a
</programlisting>
</para>
</sect3>
-<sect3 id="hoist">
-<title>For-all hoisting</title>
-<para>
-It is often convenient to use generalised type synonyms (see <xref linkend="type-synonyms"/>) at the right hand
-end of an arrow, thus:
-<programlisting>
- type Discard a = forall b. a -> b -> a
-
- g :: Int -> Discard Int
- g x y z = x+y
-</programlisting>
-Simply expanding the type synonym would give
-<programlisting>
- g :: Int -> (forall b. Int -> b -> Int)
-</programlisting>
-but GHC "hoists" the <literal>forall</literal> to give the isomorphic type
-<programlisting>
- g :: forall b. Int -> Int -> b -> Int
-</programlisting>
-In general, the rule is this: <emphasis>to determine the type specified by any explicit
-user-written type (e.g. in a type signature), GHC expands type synonyms and then repeatedly
-performs the transformation:</emphasis>
-<programlisting>
- <emphasis>type1</emphasis> -> forall a1..an. <emphasis>context2</emphasis> => <emphasis>type2</emphasis>
-==>
- forall a1..an. <emphasis>context2</emphasis> => <emphasis>type1</emphasis> -> <emphasis>type2</emphasis>
-</programlisting>
-(In fact, GHC tries to retain as much synonym information as possible for use in
-error messages, but that is a usability issue.) This rule applies, of course, whether
-or not the <literal>forall</literal> comes from a synonym. For example, here is another
-valid way to write <literal>g</literal>'s type signature:
-<programlisting>
- g :: Int -> Int -> forall b. b -> Int
-</programlisting>
-</para>
-<para>
-When doing this hoisting operation, GHC eliminates duplicate constraints. For
-example:
-<programlisting>
- type Foo a = (?x::Int) => Bool -> a
- g :: Foo (Foo Int)
-</programlisting>
-means
-<programlisting>
- g :: (?x::Int) => Bool -> Bool -> Int
-</programlisting>
-</para>
-</sect3>
</sect2>
================ END OF Linear Implicit Parameters commented out -->
-<sect2 id="sec-kinding">
+<sect2 id="kinding">
<title>Explicitly-kinded quantification</title>
<para>
g2 :: (forall a. Eq a => [a] -> a -> Bool) -> Int -> Int
f3 :: ((forall a. a->a) -> Int) -> Bool -> Bool
+
+ f4 :: Int -> (forall a. a -> a)
</programlisting>
Here, <literal>f1</literal> and <literal>g1</literal> are rank-1 types, and
can be written in standard Haskell (e.g. <literal>f1 :: a->b->a</literal>).
In particular, a forall-type (also called a "type scheme"),
including an operational type class context, is legal:
<itemizedlist>
-<listitem> <para> On the left of a function arrow </para> </listitem>
-<listitem> <para> On the right of a function arrow (see <xref linkend="hoist"/>) </para> </listitem>
+<listitem> <para> On the left or right (see <literal>f4</literal>, for example)
+of a function arrow </para> </listitem>
<listitem> <para> As the argument of a constructor, or type of a field, in a data type declaration. For
example, any of the <literal>f1,f2,f3,g1,g2</literal> above would be valid
field type signatures.</para> </listitem>
<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>
-There is one place you cannot put a <literal>forall</literal>:
-you cannot instantiate a type variable with a forall-type. So you cannot
-make a forall-type the argument of a type constructor. So these types are illegal:
-<programlisting>
- x1 :: [forall a. a->a]
- x2 :: (forall a. a->a, Int)
- x3 :: Maybe (forall a. a->a)
-</programlisting>
Of course <literal>forall</literal> becomes a keyword; you can't use <literal>forall</literal> as
a type variable any more!
</para>
<programlisting>
g :: [a] -> [a]
g (x:xs) = xs ++ [ x :: a ]
-</programlisting>
-This program will be rejected, because "<literal>a</literal>" does not scope
-over the definition of "<literal>f</literal>", so "<literal>x::a</literal>"
-means "<literal>x::forall a. a</literal>" by Haskell's usual implicit
-quantification rules.
-</para>
-</sect3>
-
-<sect3 id="exp-type-sigs">
-<title>Expression type signatures</title>
-
-<para>An expression type signature that has <emphasis>explicit</emphasis>
-quantification (using <literal>forall</literal>) brings into scope the
-explicitly-quantified
-type variables, in the annotated expression. For example:
-<programlisting>
- f = runST ( (op >>= \(x :: STRef s Int) -> g x) :: forall s. ST s Bool )
-</programlisting>
-Here, the type signature <literal>forall a. ST s Bool</literal> brings the
-type variable <literal>s</literal> into scope, in the annotated expression
-<literal>(op >>= \(x :: STRef s Int) -> g x)</literal>.
-</para>
-
-</sect3>
-
-<sect3 id="pattern-type-sigs">
-<title>Pattern type signatures</title>
-<para>
-A type signature may occur in any pattern; this is a <emphasis>pattern type
-signature</emphasis>.
-For example:
-<programlisting>
- -- f and g assume that 'a' is already in scope
- f = \(x::Int, y::a) -> x
- g (x::a) = x
- h ((x,y) :: (Int,Bool)) = (y,x)
-</programlisting>
-In the case where all the type variables in the pattern type sigature are
-already in scope (i.e. bound by the enclosing context), matters are simple: the
-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:
-<programlisting>
- data T = forall a. MkT [a]
-
- k :: T -> T
- k (MkT [t::a]) = MkT t3
- where
- 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,
-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
-<emphasis>some</emphasis> way to bring such type variables into scope, else we
-could not name existentially-bound type variables in subequent type signatures.
-</para>
-<para>
-This is (now) the <emphasis>only</emphasis> situation in which a pattern type
-signature is allowed to mention a lexical variable that is not already in
-scope.
-For example, both <literal>f</literal> and <literal>g</literal> would be
-illegal if <literal>a</literal> was not already in scope.
-</para>
-
-
-</sect3>
-
-<!-- ==================== Commented out part about result type signatures
-
-<sect3 id="result-type-sigs">
-<title>Result type signatures</title>
-
-<para>
-The result type of a function, lambda, or case expression alternative can be given a signature, thus:
-
-<programlisting>
- {- f assumes that 'a' is already in scope -}
- f x y :: [a] = [x,y,x]
-
- g = \ x :: [Int] -> [3,4]
-
- h :: forall a. [a] -> a
- h xs = case xs of
- (y:ys) :: a -> y
-</programlisting>
-The final <literal>:: [a]</literal> after the patterns of <literal>f</literal> gives the type of
-the result of the function. Similarly, the body of the lambda in the RHS of
-<literal>g</literal> is <literal>[Int]</literal>, and the RHS of the case
-alternative in <literal>h</literal> is <literal>a</literal>.
-</para>
-<para> A result type signature never brings new type variables into scope.</para>
-<para>
-There are a couple of syntactic wrinkles. First, notice that all three
-examples would parse quite differently with parentheses:
-<programlisting>
- {- f assumes that 'a' is already in scope -}
- f x (y :: [a]) = [x,y,x]
-
- g = \ (x :: [Int]) -> [3,4]
-
- h :: forall a. [a] -> a
- h xs = case xs of
- ((y:ys) :: a) -> y
-</programlisting>
-Now the signature is on the <emphasis>pattern</emphasis>; and
-<literal>h</literal> would certainly be ill-typed (since the pattern
-<literal>(y:ys)</literal> cannot have the type <literal>a</literal>.
-
-Second, to avoid ambiguity, the type after the “<literal>::</literal>” in a result
-pattern signature on a lambda or <literal>case</literal> must be atomic (i.e. a single
-token or a parenthesised type of some sort). To see why,
-consider how one would parse this:
-<programlisting>
- \ x :: a -> b -> x
-</programlisting>
-</para>
-</sect3>
-
- -->
-
-<sect3 id="cls-inst-scoped-tyvars">
-<title>Class and instance declarations</title>
-<para>
-
-The type variables in the head of a <literal>class</literal> or <literal>instance</literal> declaration
-scope over the methods defined in the <literal>where</literal> part. For example:
-
-
-<programlisting>
- class C a where
- op :: [a] -> a
-
- op xs = let ys::[a]
- ys = reverse xs
- in
- head ys
-</programlisting>
-</para>
-</sect3>
-
-</sect2>
-
-<sect2 id="deriving-typeable">
-<title>Deriving clause for classes <literal>Typeable</literal> and <literal>Data</literal></title>
-
-<para>
-Haskell 98 allows the programmer to add "<literal>deriving( Eq, Ord )</literal>" to a data type
-declaration, to generate a standard instance declaration for classes specified in the <literal>deriving</literal> clause.
-In Haskell 98, the only classes that may appear in the <literal>deriving</literal> clause are the standard
-classes <literal>Eq</literal>, <literal>Ord</literal>,
-<literal>Enum</literal>, <literal>Ix</literal>, <literal>Bounded</literal>, <literal>Read</literal>, and <literal>Show</literal>.
-</para>
-<para>
-GHC extends this list with two more classes that may be automatically derived
-(provided the <option>-fglasgow-exts</option> flag is specified):
-<literal>Typeable</literal>, and <literal>Data</literal>. These classes are defined in the library
-modules <literal>Data.Typeable</literal> and <literal>Data.Generics</literal> respectively, and the
-appropriate class must be in scope before it can be mentioned in the <literal>deriving</literal> clause.
-</para>
-<para>An instance of <literal>Typeable</literal> can only be derived if the
-data type has seven or fewer type parameters, all of kind <literal>*</literal>.
-The reason for this is that the <literal>Typeable</literal> class is derived using the scheme
-described in
-<ulink url="http://research.microsoft.com/%7Esimonpj/papers/hmap/gmap2.ps">
-Scrap More Boilerplate: Reflection, Zips, and Generalised Casts
-</ulink>.
-(Section 7.4 of the paper describes the multiple <literal>Typeable</literal> classes that
-are used, and only <literal>Typeable1</literal> up to
-<literal>Typeable7</literal> are provided in the library.)
-In other cases, there is nothing to stop the programmer writing a <literal>TypableX</literal>
-class, whose kind suits that of the data type constructor, and
-then writing the data type instance by hand.
-</para>
-</sect2>
-
-<sect2 id="newtype-deriving">
-<title>Generalised derived instances for newtypes</title>
-
-<para>
-When you define an abstract type using <literal>newtype</literal>, you may want
-the new type to inherit some instances from its representation. In
-Haskell 98, you can inherit instances of <literal>Eq</literal>, <literal>Ord</literal>,
-<literal>Enum</literal> and <literal>Bounded</literal> by deriving them, but for any
-other classes you have to write an explicit instance declaration. For
-example, if you define
-
-<programlisting>
- newtype Dollars = Dollars Int
-</programlisting>
-
-and you want to use arithmetic on <literal>Dollars</literal>, you have to
-explicitly define an instance of <literal>Num</literal>:
-
-<programlisting>
- instance Num Dollars where
- Dollars a + Dollars b = Dollars (a+b)
- ...
-</programlisting>
-All the instance does is apply and remove the <literal>newtype</literal>
-constructor. It is particularly galling that, since the constructor
-doesn't appear at run-time, this instance declaration defines a
-dictionary which is <emphasis>wholly equivalent</emphasis> to the <literal>Int</literal>
-dictionary, only slower!
-</para>
-
-
-<sect3> <title> Generalising the deriving clause </title>
-<para>
-GHC now permits such instances to be derived instead, so one can write
-<programlisting>
- newtype Dollars = Dollars Int deriving (Eq,Show,Num)
-</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>
- instance Num Int => Num Dollars
-</programlisting>
-
-which just adds or removes the <literal>newtype</literal> constructor according to the type.
-</para>
-<para>
-
-We can also derive instances of constructor classes in a similar
-way. For example, suppose we have implemented state and failure monad
-transformers, such that
-
-<programlisting>
- instance Monad m => Monad (State s m)
- instance Monad m => Monad (Failure m)
-</programlisting>
-In Haskell 98, we can define a parsing monad by
-<programlisting>
- type Parser tok m a = State [tok] (Failure m) a
-</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>
- 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>
- instance Monad (State [tok] (Failure m)) => Monad (Parser tok m)
-</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
-entire left hand side. We can imagine that the type declaration is
-``eta-converted'' to generate the context of the instance
-declaration.
+</programlisting>
+This program will be rejected, because "<literal>a</literal>" does not scope
+over the definition of "<literal>f</literal>", so "<literal>x::a</literal>"
+means "<literal>x::forall a. a</literal>" by Haskell's usual implicit
+quantification rules.
</para>
-<para>
+</sect3>
-We can even derive instances of multi-parameter classes, provided the
-newtype is the last class parameter. In this case, a ``partial
-application'' of the class appears in the <literal>deriving</literal>
-clause. For example, given the class
+<sect3 id="exp-type-sigs">
+<title>Expression type signatures</title>
-<programlisting>
- class StateMonad s m | m -> s where ...
- instance Monad m => StateMonad s (State s m) where ...
-</programlisting>
-then we can derive an instance of <literal>StateMonad</literal> for <literal>Parser</literal>s by
-<programlisting>
- newtype Parser tok m a = Parser (State [tok] (Failure m) a)
- deriving (Monad, StateMonad [tok])
+<para>An expression type signature that has <emphasis>explicit</emphasis>
+quantification (using <literal>forall</literal>) brings into scope the
+explicitly-quantified
+type variables, in the annotated expression. For example:
+<programlisting>
+ f = runST ( (op >>= \(x :: STRef s Int) -> g x) :: forall s. ST s Bool )
</programlisting>
+Here, the type signature <literal>forall a. ST s Bool</literal> brings the
+type variable <literal>s</literal> into scope, in the annotated expression
+<literal>(op >>= \(x :: STRef s Int) -> g x)</literal>.
+</para>
-The derived instance is obtained by completing the application of the
-class to the new type:
+</sect3>
-<programlisting>
- instance StateMonad [tok] (State [tok] (Failure m)) =>
- StateMonad [tok] (Parser tok m)
+<sect3 id="pattern-type-sigs">
+<title>Pattern type signatures</title>
+<para>
+A type signature may occur in any pattern; this is a <emphasis>pattern type
+signature</emphasis>.
+For example:
+<programlisting>
+ -- f and g assume that 'a' is already in scope
+ f = \(x::Int, y::a) -> x
+ g (x::a) = x
+ h ((x,y) :: (Int,Bool)) = (y,x)
</programlisting>
+In the case where all the type variables in the pattern type sigature are
+already in scope (i.e. bound by the enclosing context), matters are simple: the
+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:
+<programlisting>
+ data T = forall a. MkT [a]
-As a result of this extension, all derived instances in newtype
- declarations are treated uniformly (and implemented just by reusing
-the dictionary for the representation type), <emphasis>except</emphasis>
-<literal>Show</literal> and <literal>Read</literal>, which really behave differently for
-the newtype and its representation.
+ k :: T -> T
+ k (MkT [t::a]) = MkT t3
+ where
+ 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,
+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
+<emphasis>some</emphasis> way to bring such type variables into scope, else we
+could not name existentially-bound type variables in subequent type signatures.
+</para>
+<para>
+This is (now) the <emphasis>only</emphasis> situation in which a pattern type
+signature is allowed to mention a lexical variable that is not already in
+scope.
+For example, both <literal>f</literal> and <literal>g</literal> would be
+illegal if <literal>a</literal> was not already in scope.
</para>
+
+
</sect3>
-<sect3> <title> A more precise specification </title>
+<!-- ==================== Commented out part about result type signatures
+
+<sect3 id="result-type-sigs">
+<title>Result type signatures</title>
+
<para>
-Derived instance declarations are constructed as follows. Consider the
-declaration (after expansion of any type synonyms)
+The result type of a function, lambda, or case expression alternative can be given a signature, thus:
-<programlisting>
- newtype T v1...vn = T' (t vk+1...vn) deriving (c1...cm)
-</programlisting>
+<programlisting>
+ {- f assumes that 'a' is already in scope -}
+ f x y :: [a] = [x,y,x]
-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>
- 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.
-</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
-</para></listitem>
-<listitem><para>
- None of the <literal>ci</literal> is <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>
-</itemizedlist>
-Then, for each <literal>ci</literal>, the derived instance
-declaration is:
-<programlisting>
- instance ci t => ci (T v1...vk)
-</programlisting>
-As an example which does <emphasis>not</emphasis> work, consider
-<programlisting>
- newtype NonMonad m s = NonMonad (State s m s) deriving Monad
-</programlisting>
-Here we cannot derive the instance
-<programlisting>
- instance Monad (State s m) => Monad (NonMonad m)
-</programlisting>
+ g = \ x :: [Int] -> [3,4]
-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
-<literal>deriving</literal> clause is rejected, because <literal>NonMonad m</literal> is
-not, in fact, a monad --- for the same reason. Try defining
-<literal>>>=</literal> with the correct type: you won't be able to.
+ h :: forall a. [a] -> a
+ h xs = case xs of
+ (y:ys) :: a -> y
+</programlisting>
+The final <literal>:: [a]</literal> after the patterns of <literal>f</literal> gives the type of
+the result of the function. Similarly, the body of the lambda in the RHS of
+<literal>g</literal> is <literal>[Int]</literal>, and the RHS of the case
+alternative in <literal>h</literal> is <literal>a</literal>.
</para>
+<para> A result type signature never brings new type variables into scope.</para>
<para>
+There are a couple of syntactic wrinkles. First, notice that all three
+examples would parse quite differently with parentheses:
+<programlisting>
+ {- f assumes that 'a' is already in scope -}
+ f x (y :: [a]) = [x,y,x]
-Notice also that the <emphasis>order</emphasis> of class parameters becomes
-important, since we can only derive instances for the last one. If the
-<literal>StateMonad</literal> class above were instead defined as
+ g = \ (x :: [Int]) -> [3,4]
-<programlisting>
- class StateMonad m s | m -> s where ...
+ h :: forall a. [a] -> a
+ h xs = case xs of
+ ((y:ys) :: a) -> y
</programlisting>
+Now the signature is on the <emphasis>pattern</emphasis>; and
+<literal>h</literal> would certainly be ill-typed (since the pattern
+<literal>(y:ys)</literal> cannot have the type <literal>a</literal>.
-then we would not have been able to derive an instance for the
-<literal>Parser</literal> type above. We hypothesise that multi-parameter
-classes usually have one "main" parameter for which deriving new
-instances is most interesting.
-</para>
-<para>Lastly, all of this applies only for classes other than
-<literal>Read</literal>, <literal>Show</literal>, <literal>Typeable</literal>,
-and <literal>Data</literal>, for which the built-in derivation applies (section
-4.3.3. of the Haskell Report).
-(For the standard classes <literal>Eq</literal>, <literal>Ord</literal>,
-<literal>Ix</literal>, and <literal>Bounded</literal> it is immaterial whether
-the standard method is used or the one described here.)
+Second, to avoid ambiguity, the type after the “<literal>::</literal>” in a result
+pattern signature on a lambda or <literal>case</literal> must be atomic (i.e. a single
+token or a parenthesised type of some sort). To see why,
+consider how one would parse this:
+<programlisting>
+ \ x :: a -> b -> x
+</programlisting>
</para>
</sect3>
-</sect2>
-
-<sect2 id="stand-alone-deriving">
-<title>Stand-alone deriving declarations</title>
+ -->
+<sect3 id="cls-inst-scoped-tyvars">
+<title>Class and instance declarations</title>
<para>
-GHC now allows stand-alone <literal>deriving</literal> declarations:
-</para>
-
-<programlisting>
- data Foo = Bar Int | Baz String
- deriving Eq for Foo
-</programlisting>
+The type variables in the head of a <literal>class</literal> or <literal>instance</literal> declaration
+scope over the methods defined in the <literal>where</literal> part. For example:
-<para>Deriving instances of multi-parameter type classes for newtypes is
-also allowed:</para>
<programlisting>
- newtype Foo a = MkFoo (State Int a)
+ class C a where
+ op :: [a] -> a
- deriving (MonadState Int) for Foo
+ op xs = let ys::[a]
+ ys = reverse xs
+ in
+ head ys
</programlisting>
-
-<para>
</para>
+</sect3>
</sect2>
+
<sect2 id="typing-binds">
<title>Generalised typing of mutually recursive bindings</title>
</para>
</sect2>
+<sect2 id="overloaded-strings">
+<title>Overloaded string literals
+</title>
+
+<para>
+GHC supports <emphasis>overloaded string literals</emphasis>. Normally a
+string literal has type <literal>String</literal>, but with overloaded string
+literals enabled (with <literal>-foverloaded-strings</literal>)
+ a string literal has type <literal>(IsString a) => a</literal>.
+</para>
+<para>
+This means that the usual string syntax can be used, e.g., for packed strings
+and other variations of string like types. String literals behave very much
+like integer literals, i.e., they can be used in both expressions and patterns.
+If used in a pattern the literal with be replaced by an equality test, in the same
+way as an integer literal is.
+</para>
+<para>
+The class <literal>IsString</literal> is defined as:
+<programlisting>
+class IsString a where
+ fromString :: String -> a
+</programlisting>
+The only predefined instance is the obvious one to make strings work as usual:
+<programlisting>
+instance IsString [Char] where
+ fromString cs = cs
+</programlisting>
+The class <literal>IsString</literal> is not in scope by default. If you want to mention
+it explicitly (for exmaple, to give an instance declaration for it), you can import it
+from module <literal>GHC.Exts</literal>.
+</para>
+<para>
+Haskell's defaulting mechanism is extended to cover string literals, when <option>-foverloaded-strings</option> is specified.
+Specifically:
+<itemizedlist>
+<listitem><para>
+Each type in a default declaration must be an
+instance of <literal>Num</literal> <emphasis>or</emphasis> of <literal>IsString</literal>.
+</para></listitem>
+
+<listitem><para>
+The standard defaulting rule (<ulink url="http://haskell.org/onlinereport/decls.html#sect4.3.4">Haskell Report, Section 4.3.4</ulink>)
+is extended thus: defaulting applies when all the unresolved constraints involve standard classes
+<emphasis>or</emphasis> <literal>IsString</literal>; and at least one is a numeric class
+<emphasis>or</emphasis> <literal>IsString</literal>.
+</para></listitem>
+</itemizedlist>
+</para>
+<para>
+A small example:
+<programlisting>
+module Main where
+
+import GHC.Exts( IsString(..) )
+
+newtype MyString = MyString String deriving (Eq, Show)
+instance IsString MyString where
+ fromString = MyString
+
+greet :: MyString -> MyString
+greet "hello" = "world"
+greet other = other
+
+main = do
+ print $ greet "hello"
+ print $ greet "fool"
+</programlisting>
+</para>
+<para>
+Note that deriving <literal>Eq</literal> is necessary for the pattern matching
+to work since it gets translated into an equality comparison.
+</para>
+</sect2>
+
</sect1>
<!-- ==================== End of type system extensions ================= -->
(It would make sense to do so, but it's hard to implement.)
</para></listitem>
+ <listitem><para>
+ Furthermore, you can only run a function at compile time if it is imported
+ from another module <emphasis>that is not part of a mutually-recursive group of modules
+ that includes the module currently being compiled</emphasis>. For example, when compiling module A,
+ you can only run Template Haskell functions imported from B if B does not import A (directly or indirectly).
+ The reason should be clear: to run B we must compile and run A, but we are currently type-checking A.
+ </para></listitem>
+
<listitem><para>
The flag <literal>-ddump-splices</literal> shows the expansion of all top-level splices as they happen.
</para></listitem>
<!-- ==================== BANG PATTERNS ================= -->
-<sect1 id="sec-bang-patterns">
+<sect1 id="bang-patterns">
<title>Bang patterns
<indexterm><primary>Bang patterns</primary></indexterm>
</title>
Bang patterns are enabled by the flag <option>-fbang-patterns</option>.
</para>
-<sect2 id="sec-bang-patterns-informal">
+<sect2 id="bang-patterns-informal">
<title>Informal description of bang patterns
</title>
<para>
</sect2>
-<sect2 id="sec-bang-patterns-sem">
+<sect2 id="bang-patterns-sem">
<title>Syntax and semantics
</title>
<para>
<!-- ==================== ASSERTIONS ================= -->
-<sect1 id="sec-assertions">
+<sect1 id="assertions">
<title>Assertions
<indexterm><primary>Assertions</primary></indexterm>
</title>
<listitem>
<para>
- <function>length</function>
-</para>
-</listitem>
-<listitem>
-
-<para>
<function>++</function> (on its first argument)
</para>
</listitem>