you should be all right.</para>
</sect2>
+
+<sect2 id="postfix-operators">
+<title>Postfix operators</title>
+
+<para>
+GHC allows a small extension to the syntax of left operator sections, which
+allows you to define postfix operators. The extension is this: the left section
+<programlisting>
+ (e !)
+</programlisting>
+is equivalent (from the point of view of both type checking and execution) to the expression
+<programlisting>
+ ((!) e)
+</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>
+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.
+</para>
+<para>Since this extension goes beyond Haskell 98, it should really be enabled
+by a flag; but in fact it is enabled all the time. (No Haskell 98 programs
+change their behaviour, of course.)
+</para>
+<para>The extension does not extend to the left-hand side of function
+definitions; you must define such a function in prefix form.</para>
+
+</sect2>
+
</sect1>
where
<itemizedlist>
<listitem><para>
- The type <literal>t</literal> is an arbitrary type
+ 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>vk+1...vn</literal> are type variables which do not occur in
- <literal>t</literal>, and
+ The <literal>k</literal> is chosen so that <literal>ci (T v1...vk)</literal> is well-kinded.
</para></listitem>
<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.
+ 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>,
Then, for each <literal>ci</literal>, the derived instance
declaration is:
<programlisting>
- instance ci (t vk+1...v) => ci (T v1...vp)
+ instance ci t => ci (T v1...vk)
</programlisting>
-where <literal>p</literal> is chosen so that <literal>T v1...vp</literal> is of the
-right <emphasis>kind</emphasis> for the last parameter of class <literal>Ci</literal>.
-</para>
-<para>
-
As an example which does <emphasis>not</emphasis> work, consider
<programlisting>
newtype NonMonad m s = NonMonad (State s m s) deriving Monad
Haskell-98 syntax. For example, these two declarations are equivalent
<programlisting>
data Maybe1 a where {
- Nothing1 :: Maybe a ;
- Just1 :: a -> Maybe a
+ Nothing1 :: Maybe1 a ;
+ Just1 :: a -> Maybe1 a
} deriving( Eq, Ord )
data Maybe2 a = Nothing2 | Just2 a
GHCziBase.ZMZN GHCziBase.Char -> GHCziBase.ZMZN GHCziBase.Cha
r) ->
tpl2})
- (%note "foo"
+ (%note "bar"
eta);
</programlisting>
<sect1 id="generic-classes">
<title>Generic classes</title>
- <para>(Note: support for generic classes is currently broken in
- GHC 5.02).</para>
-
<para>
The ideas behind this extension are described in detail in "Derivable type classes",
Ralf Hinze and Simon Peyton Jones, Haskell Workshop, Montreal Sept 2000, pp94-105.