In message <[EMAIL PROTECTED]>, David Barton writes:
> When I enter the following module and load it into Hugs:
> 
> > module Main where
> > plus = zipWith (+)
> > main = putStr (show (plus [1.0] [2.0]))
>   
> 
> Hugs then gives the following error:
> 
> Prelude> :l test.lhs
> Reading file "test.lhs":
> Type checking      
> ERROR "test.lhs" (line 5): Int is not an instance of class "Fractional"
> Prelude> 
>
[snip]
>
> When submitted to ghc version 2.06, the above program compiles with no
> problem.  It executes, and gives [3.0] as expected.
> 
> This appears to be a disagreement in the interpretation of the
> monomorphism restriction.  Rule 2 seems to apply.  In particular, the
> example in the report seems directly applicable.  Mind you, I never
> *have* really understood the monomorphism restriction --- I just
> scatter type signatures everywhere (as I believe good programming
> practice requires), and things work out fine.
> 
> So which is correct, Hugs or GHC 2.06?

    I vote GHC, even though I use Hugs more often, and I have no
relation with Glasgow.  I take the position on this matter just because
the module system of GHC seems to be more consistent than that of Hugs.
Mind you, I don't think I have understood the monomorphism restriction
properly.   I'm writing this mail just becuase  I'd like to hear expert
comments on this tipic from the developers and the theoreticians.

    Summary: Hugs type checker appears to treat each top-level binding group
like a (sub-)module exporting all the bound variables in the group.
This property appears to be inherited from Gofer.


-*-*-*-*-  the following is just my understanding -*-*-*-*-
    
    Hugs tries to resolve the context of a restricted type variable
whenever a top-level binding group is typed, without taking into
account how the variables in the group are used later in the same
module.  To illustrate, consider the following script:

> module Main where
> plus = zipWith (+)
> main = putStr (show (plus [1.0] [2.0]))

The bindings are split up into two top-level binding groups by the static
analyzer: {plus} and {main}.  The group {plus} is typed first,
and Hugs concludes

        {Num a} | zipWith : (forall a).((a->a->a) -> [a] -> [a] -> [a]),
                  (+)     : (forall a).(Num a => a -> a -> a),
                  ... a is free here ...
                |- plus : [a] -> [a] -> [a].

Because of the monomorphism restriction rule 1, the constrained type
variable a is not generalized.  (Generalization would assign
forall a.Num a => [a] -> [a] -> [a] to plus.)   Hugs differs from GHC
in the method of manipulating this ``suspended'' or ambiguous predicate:

   Hugs tries to apply the default declaration to eliminate the predidate.
       This implies that the monomorphism restriction rule 2 is automatically
       satisfied.  If Hugs fails, it reports it as an error.

   GHC leaves it anticipating that this ambiguity may be resolved later.
       The monomorphism restriction rule 2 and ambiguously overloaded types
       are taken into account only after all the bindings in a module are
       typed.  If GHC fails even at that point it reports it as an error.

Reply via email to