Add -fextended-default-rules and -fmono-pat-binds
authorsimonpj@microsoft.com <unknown>
Mon, 7 Aug 2006 11:21:07 +0000 (11:21 +0000)
committersimonpj@microsoft.com <unknown>
Mon, 7 Aug 2006 11:21:07 +0000 (11:21 +0000)
Add -fextended-deafult-rules (in response to Don Stewart's message below),
and document them.

Also doucument -fmono-pat-binds/-fno-mono-pat-binds, which has been in
GHC a few weeks now.

(The two are in one patch because the diffs were so close together
that Darcs combined them.)

Simon

From: Donald Bruce Stewart [mailto:dons@cse.unsw.edu.au]
Sent: 07 August 2006 10:52

While we're thinking about defaulting, I have a question..

ghci uses an extended defaulting system, to allow things like:
        Prelude> reverse []
        []
to work, and to have the right instance of Show found. The manual says:

    "..it is tiresome for the user to have to specify the type, so GHCi extends
    Haskell's type-defaulting rules (Section 4.3.4 of the Haskell 98 Report
    (Revised)) as follows. If the expression yields a set of type constraints
    that are all from standard classes (Num, Eq etc.), and at least one is
    either a numeric class or the Show, Eq, or Ord class, GHCi will try to use
    one of the default types, just as described in the Report. The standard
    defaulting rules require that one of the classes is numeric; the difference
    here is that defaulting is also triggered at least one is Show, Eq, or Ord."

Currently, there is no way to get at this "extended" defaulting for compiled
modules. However, I have a use case for in fact doing this.

With runtime evaluated Haskell, embedding 'interpreters' (over hs-plugins) is
easy. lambdabot, for example, implements a sandboxed haskell eval system. But
it doesn't have access to the defaulting mechanism of ghci, so we have:

    dons:: > reverse []
    lambdabot:: Add a type signature
    dons:: > reverse [] :: [()]
    lambdabot:: []

Which is annoying -- newbies wonder why they have to add these extra
constraints to get a Show instance.

I'm wondering, since the extended defaulting mechanisms are already
implemented, could they be made available to compiled modules as well,
perhaps using a flag, -fextended-defaulting?

compiler/main/DynFlags.hs
compiler/typecheck/TcSimplify.lhs
docs/users_guide/flags.xml
docs/users_guide/ghci.xml
docs/users_guide/glasgow_exts.xml

index a5269c0..f02e676 100644 (file)
@@ -154,10 +154,11 @@ data DynFlag
    | Opt_AllowIncoherentInstances
    | Opt_MonomorphismRestriction
    | Opt_MonoPatBinds
+   | Opt_ExtendedDefaultRules          -- Use GHC's extended rules for defaulting
    | Opt_GlasgowExts
    | Opt_FFI
-   | Opt_PArr                         -- syntactic support for parallel arrays
-   | Opt_Arrows                               -- Arrow-notation syntax
+   | Opt_PArr                          -- Syntactic support for parallel arrays
+   | Opt_Arrows                                -- Arrow-notation syntax
    | Opt_TH
    | Opt_ImplicitParams
    | Opt_Generics
@@ -1015,6 +1016,7 @@ fFlags = [
   ( "bang-patterns",                   Opt_BangPatterns ),
   ( "monomorphism-restriction",                Opt_MonomorphismRestriction ),
   ( "mono-pat-binds",                  Opt_MonoPatBinds ),
+  ( "extended-default-rules",          Opt_ExtendedDefaultRules ),
   ( "implicit-params",                 Opt_ImplicitParams ),
   ( "allow-overlapping-instances",     Opt_AllowOverlappingInstances ),
   ( "allow-undecidable-instances",     Opt_AllowUndecidableInstances ),
index dae3c82..e142418 100644 (file)
@@ -71,7 +71,8 @@ import Util           ( zipEqual, isSingleton )
 import List            ( partition )
 import SrcLoc          ( Located(..) )
 import DynFlags                ( DynFlags(ctxtStkDepth), 
-                         DynFlag( Opt_GlasgowExts, Opt_AllowUndecidableInstances, Opt_WarnTypeDefaults ) )
+                         DynFlag( Opt_GlasgowExts, Opt_AllowUndecidableInstances, 
+                         Opt_WarnTypeDefaults, Opt_ExtendedDefaultRules ) )
 \end{code}
 
 
@@ -921,7 +922,8 @@ Two more nasty cases are in
 tcSimplifySuperClasses qtvs givens sc_wanteds
   = ASSERT( all isSkolemTyVar qtvs )
     do { (_, frees, binds1) <- tcSimplCheck doc get_qtvs NoSCs givens sc_wanteds
-       ; binds2             <- tc_simplify_top doc False NoSCs frees
+       ; ext_default        <- doptM Opt_ExtendedDefaultRules
+       ; binds2             <- tc_simplify_top doc ext_default NoSCs frees
        ; return (binds1 `unionBags` binds2) }
   where
     get_qtvs = return (mkVarSet qtvs)
@@ -2009,7 +2011,8 @@ It's OK: the final zonking stage should zap y to (), which is fine.
 \begin{code}
 tcSimplifyTop, tcSimplifyInteractive :: [Inst] -> TcM TcDictBinds
 tcSimplifyTop wanteds
-  = tc_simplify_top doc False {- Not interactive loop -} AddSCs wanteds
+  = do         { ext_default <- doptM Opt_ExtendedDefaultRules
+       ; tc_simplify_top doc ext_default AddSCs wanteds }
   where 
     doc = text "tcSimplifyTop"
 
@@ -2020,7 +2023,7 @@ tcSimplifyInteractive wanteds
 
 -- The TcLclEnv should be valid here, solely to improve
 -- error message generation for the monomorphism restriction
-tc_simplify_top doc is_interactive want_scs wanteds
+tc_simplify_top doc use_extended_defaulting want_scs wanteds
   = do { lcl_env <- getLclEnv
        ; traceTc (text "tcSimplifyTop" <+> ppr (lclEnvElts lcl_env))
 
@@ -2046,13 +2049,13 @@ tc_simplify_top doc is_interactive want_scs wanteds
                =  not (bad_tyvars `intersectsVarSet` tyVarsOfInst (head ds))
                && defaultable_classes (map get_clas ds)
            defaultable_classes clss 
-               | is_interactive = any isInteractiveClass clss
-               | otherwise      = all isStandardClass clss && any isNumericClass clss
+               | use_extended_defaulting = any isInteractiveClass clss
+               | otherwise = all isStandardClass clss && any isNumericClass clss
 
            isInteractiveClass cls = isNumericClass cls
                                  || (classKey cls `elem` [showClassKey, eqClassKey, ordClassKey])
-                       -- In interactive mode, we default Show a to Show ()
-                       -- to avoid graututious errors on "show []"
+                       -- In interactive mode, or with -fextended-default-rules,
+                       -- we default Show a to Show () to avoid graututious errors on "show []"
 
     
                    -- Collect together all the bad guys
index 6d6ef86..958fa3c 100644 (file)
              <entry><option>-fmonomorphism-restriction</option></entry>
            </row>
            <row>
+             <entry><option>-fno-mono-pat-binds</option></entry>
+             <entry>Make pattern bindings polymorphic</entry>
+             <entry>dynamic</entry>
+             <entry><option>-fmono-pat-binds</option></entry>
+           </row>
+           <row>
+             <entry><option>-fextended-default-rules</option></entry>
+             <entry>Use GHCi's extended default rules in a normal module</entry>
+             <entry>dynamic</entry>
+             <entry><option>-fno-extended-default-rules</option></entry>
+           </row>
+           <row>
              <entry><option>-fscoped-type-variables</option></entry>
              <entry>Enable lexically-scoped type variables.
              Implied by <option>-fglasgow-exts</option>.</entry>
     <sect2>
       <title>Warnings</title>
       
-      <para>(<xref linkend="options-sanity"/></para>
+      <para><xref linkend="options-sanity"/></para>
 
     <informaltable>
       <tgroup cols="4" align="left" colsep="1" rowsep="1">
index 786815d..1736757 100644 (file)
@@ -676,7 +676,7 @@ Wed Mar 14 12:23:13 GMT 2001
 
     </sect2>
 
-    <sect2>
+    <sect2 id="extended-default-rules">
       <title>Type defaulting in GHCi</title>
     <indexterm><primary>Type default</primary></indexterm>
     <indexterm><primary><literal>Show</literal> class</primary></indexterm>
@@ -715,6 +715,8 @@ Wed Mar 14 12:23:13 GMT 2001
            numeric, <emphasis>or is <literal>Show</literal>, 
                <literal>Eq</literal>, or <literal>Ord</literal></emphasis>.</para></listitem>
       </itemizedlist>
+   The same type-default behaviour can be enabled in an ordinary Haskell
+   module, using the flag <literal>-fextended-default-rules</literal>.
    </para>
     </sect2>
   </sect1>
index f803f6d..0beed8e 100644 (file)
@@ -128,6 +128,45 @@ documentation</ulink> describes all the libraries that come with GHC.
 
       <varlistentry>
        <term>
+          <option>-fno-mono-pat-binds</option>:
+          <indexterm><primary><option>-fno-mono-pat-binds</option></primary></indexterm>
+          <indexterm><primary><option>-fmono-pat-binds</option></primary></indexterm>
+        </term>
+       <listitem>
+         <para> As an experimental change, we are exploring the possibility of
+         making pattern bindings monomorphic; that is, not generalised at all.  
+           A pattern binding is a binding whose LHS has no function arguments,
+           and is not a simple variable.  For example:
+<programlisting>
+  f x = x                    -- Not a pattern binding
+  f = \x -> x                -- Not a pattern binding
+  f :: Int -> Int = \x -> x  -- Not a pattern binding
+
+  (g,h) = e                  -- A pattern binding
+  (f) = e                    -- A pattern binding
+  [x] = e                    -- A pattern binding
+</programlisting>
+Experimentally, GHC now makes pattern bindings monomorphic <emphasis>by
+default</emphasis>.  Use <option>-fno-mono-pat-binds</option> to recover the
+standard behaviour.
+          </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>
+          <option>-fextended-default-rules</option>:
+          <indexterm><primary><option>-fextended-default-rules</option></primary></indexterm>
+        </term>
+       <listitem>
+         <para> Use GHCi's extended default rules in a regular module (<xref linkend="extended-default-rules"/>).
+          Independent of the <option>-fglasgow-exts</option>
+          flag. </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>
           <option>-fallow-overlapping-instances</option>
           <indexterm><primary><option>-fallow-overlapping-instances</option></primary></indexterm>
         </term>