[project @ 2005-07-25 11:11:36 by simonpj]
[ghc-hetmet.git] / ghc / docs / users_guide / glasgow_exts.xml
index aecfcbc..9e712f8 100644 (file)
@@ -1427,7 +1427,7 @@ declarations.  Define your own instances!
 <para>
 This section documents GHC's implementation of multi-parameter type
 classes.  There's lots of background in the paper <ulink
-url="http://research.microsoft.com/~simonpj/multi.ps.gz" >Type
+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>
@@ -3413,6 +3413,68 @@ the standard method is used or the one described here.)
 
 </sect2>
 
+<sect2 id="typing-binds">
+<title>Generalised typing of mutually recursive bindings</title>
+
+<para>
+The Haskell Report specifies that a group of bindings (at top level, or in a
+<literal>let</literal> or <literal>where</literal>) should be sorted into
+strongly-connected components, and then type-checked in dependency order
+(<ulink url="http://haskell.org/onlinereport/decls.html#sect4.5.1">Haskell
+Report, Section 4.5.1</ulink>).  
+As each group is type-checked, any binders of the group that
+have
+an explicit type signature are put in the type environment with the specified
+polymorphic type,
+and all others are monomorphic until the group is generalised 
+(<ulink url="http://haskell.org/onlinereport/decls.html#sect4.5.2">Haskell Report, Section 4.5.2</ulink>).
+</para>
+
+<para>Following a suggestion of Mark Jones, in his paper
+<ulink url="http://www.cse.ogi.edu/~mpj/thih/">Typing Haskell in
+Haskell</ulink>,
+GHC implements a more general scheme.  If <option>-fglasgow-exts</option> is
+specified:
+<emphasis>the dependency analysis ignores references to variables that have an explicit
+type signature</emphasis>.
+As a result of this refined dependency analysis, the dependency groups are smaller, and more bindings will
+typecheck.  For example, consider:
+<programlisting>
+  f :: Eq a =&gt; a -> Bool
+  f x = (x == x) || g True || g "Yes"
+  
+  g y = (y &lt;= y) || f True
+</programlisting>
+This is rejected by Haskell 98, but under Jones's scheme the definition for
+<literal>g</literal> is typechecked first, separately from that for
+<literal>f</literal>,
+because the reference to <literal>f</literal> in <literal>g</literal>'s right
+hand side is ingored by the dependency analysis.  Then <literal>g</literal>'s
+type is generalised, to get
+<programlisting>
+  g :: Ord a =&gt; a -> Bool
+</programlisting>
+Now, the defintion for <literal>f</literal> is typechecked, with this type for
+<literal>g</literal> in the type environment.
+</para>
+
+<para>
+The same refined dependency analysis also allows the type signatures of 
+mutually-recursive functions to have different contexts, something that is illegal in
+Haskell 98 (Section 4.5.2, last sentence).  With
+<option>-fglasgow-exts</option>
+GHC only insists that the type signatures of a <emphasis>refined</emphasis> group have identical
+type signatures; in practice this means that only variables bound by the same
+pattern binding must have the same context.  For example, this is fine:
+<programlisting>
+  f :: Eq a =&gt; a -> Bool
+  f x = (x == x) || g True
+  
+  g :: Ord a =&gt; a -> Bool
+  g y = (y &lt;= y) || f True
+</programlisting>
+</para>
+</sect2>
 
 </sect1>
 <!-- ==================== End of type system extensions =================  -->
@@ -3473,9 +3535,10 @@ type above, the type of each constructor must end with <literal> ... -> Term ...
 </para></listitem>
 
 <listitem><para>
-You cannot use a <literal>deriving</literal> clause on a GADT-style data type declaration,
-nor can you use record syntax.  (It's not clear what these constructs would mean.  For example,
-the record selectors might ill-typed.)  However, you can use strictness annotations, in the obvious places
+You cannot use record syntax on a GADT-style data type declaration.  (
+It's not clear what these it would mean.  For example,
+the record selectors might ill-typed.)
+However, you can use strictness annotations, in the obvious places
 in the constructor type:
 <programlisting>
   data Term a where
@@ -3486,6 +3549,23 @@ in the constructor type:
 </para></listitem>
 
 <listitem><para>
+You can use a <literal>deriving</literal> clause on a GADT-style data type
+declaration, but only if the data type could also have been declared in
+Haskell-98 syntax.   For example, these two declarations are equivalent
+<programlisting>
+  data Maybe1 a where {
+      Nothing1 :: Maybe a ;
+      Just1    :: a -> Maybe a
+    } deriving( Eq, Ord )
+
+  data Maybe2 a = Nothing2 | Just2 a 
+       deriving( Eq, Ord )
+</programlisting>
+This simply allows you to declare a vanilla Haskell-98 data type using the
+<literal>where</literal> form without losing the <literal>deriving</literal> clause.
+</para></listitem>
+
+<listitem><para>
 Pattern matching causes type refinement.  For example, in the right hand side of the equation
 <programlisting>
   eval :: Term a -> a
@@ -3569,9 +3649,11 @@ Tim Sheard is going to expand it.)
                  </para>
              <para> A splice can occur in place of 
                  <itemizedlist>
-                   <listitem><para> an expression; the spliced expression must have type <literal>Expr</literal></para></listitem>
+                   <listitem><para> an expression; the spliced expression must
+                   have type <literal>Q Exp</literal></para></listitem>
                    <listitem><para> a list of top-level declarations; ; the spliced expression must have type <literal>Q [Dec]</literal></para></listitem>
-                   <listitem><para> a type; the spliced expression must have type <literal>Type</literal>.</para></listitem>
+                   <listitem><para> [Planned, but not implemented yet.] a
+                   type; the spliced expression must have type <literal>Q Typ</literal>.</para></listitem>
                    </itemizedlist>
           (Note that the syntax for a declaration splice uses "<literal>$</literal>" not "<literal>splice</literal>" as in
        the paper. Also the type of the enclosed expression must be  <literal>Q [Dec]</literal>, not  <literal>[Q Dec]</literal>
@@ -3586,7 +3668,7 @@ Tim Sheard is going to expand it.)
                              the quotation has type <literal>Expr</literal>.</para></listitem>
                    <listitem><para> <literal>[d| ... |]</literal>, where the "..." is a list of top-level declarations;
                              the quotation has type <literal>Q [Dec]</literal>.</para></listitem>
-                   <listitem><para> <literal>[t| ... |]</literal>, where the "..." is a type; 
+                   <listitem><para>  [Planned, but not implemented yet.]  <literal>[t| ... |]</literal>, where the "..." is a type; 
                              the quotation has type <literal>Type</literal>.</para></listitem>
                  </itemizedlist></para></listitem>
 
@@ -4331,7 +4413,7 @@ Assertion failures can be caught, see the documentation for the
        </listitem>
 
        <listitem>
-         <para>You can deprecate a function, class, or type, with the
+         <para>You can deprecate a function, class, type, or data constructor, with the
          following top-level declaration:</para>
 <programlisting>
    {-# DEPRECATED f, C, T "Don't use these" #-}
@@ -4339,6 +4421,13 @@ Assertion failures can be caught, see the documentation for the
          <para>When you compile any module that imports and uses any
           of the specified entities, GHC will print the specified
           message.</para>
+         <para> You can only depecate entities declared at top level in the module
+         being compiled, and you can only use unqualified names in the list of
+         entities being deprecated.  A capitalised name, such as <literal>T</literal>
+         refers to <emphasis>either</emphasis> the type constructor <literal>T</literal>
+         <emphasis>or</emphasis> the data constructor <literal>T</literal>, or both if
+         both are in scope.  If both are in scope, there is currently no way to deprecate 
+         one without the other (c.f. fixities <xref linkend="infix-tycons"/>).</para>
        </listitem>
       </itemizedlist>
       Any use of the deprecated item, or of anything from a deprecated
@@ -4587,7 +4676,7 @@ key_function :: Int -> String -> (Bool, Double)
       overloaded function:</para>
 
 <programlisting>
-hammeredLookup :: Ord key => [(key, value)] -> key -> value
+  hammeredLookup :: Ord key => [(key, value)] -> key -> value
 </programlisting>
 
       <para>If it is heavily used on lists with
@@ -4595,7 +4684,7 @@ hammeredLookup :: Ord key => [(key, value)] -> key -> value
       follows:</para>
 
 <programlisting>
-{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
+  {-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
 </programlisting>
 
       <para>A <literal>SPECIALIZE</literal> pragma for a function can
@@ -4606,7 +4695,35 @@ hammeredLookup :: Ord key => [(key, value)] -> key -> value
       (see <xref linkend="rewrite-rules"/>) that rewrites a call to the
       un-specialised function into a call to the specialised one.</para>
 
-      <para>In earlier versions of GHC, it was possible to provide your own
+      <para>The type in a SPECIALIZE pragma can be any type that is less
+       polymorphic than the type of the original function.  In concrete terms,
+       if the original function is <literal>f</literal> then the pragma
+<programlisting>
+  {-# SPECIALIZE f :: &lt;type&gt; #-}
+</programlisting>
+      is valid if and only if the defintion
+<programlisting>
+  f_spec :: &lt;type&gt;
+  f_spec = f
+</programlisting>
+      is valid.  Here are some examples (where we only give the type signature
+      for the original function, not its code):
+<programlisting>
+  f :: Eq a => a -> b -> b
+  {-# SPECIALISE g :: Int -> b -> b #-}
+
+  g :: (Eq a, Ix b) => a -> b -> b
+  {-# SPECIALISE g :: (Eq a) => a -> Int -> Int #-}
+
+  h :: Eq a => a -> a -> a
+  {-# SPECIALISE h :: (Eq a) => [a] -> [a] -> [a] #-}
+</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.
+</para>
+
+      <para>Note: In earlier versions of GHC, it was possible to provide your own
       specialised function for a given type:
 
 <programlisting>