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.