[Haskell] Re: Implicit type of numeric constants
R.J.Stroud at ncl.ac.uk
Thu Sep 21 05:25:22 EDT 2006
Thanks for your explanation - this is beginning to make more sense to
me. However, I'm not finding it easy to follow the Haskell language
manual, and understand how the rules apply, so please could you
confirm that the following reasoning is correct...
Firstly, am I right in thinking that "k = 2" is a simple pattern
binding? The syntax for a top-level declaration doesn't seem to
include the possibility of declaring a variable, and there doesn't
seem to be an explicit syntax for pattern.
However, assuming "k = 2" is a simple pattern, then it would be a
restricted declaration group (because there is no explicit type
signature for k ), and so the monomorphism restriction says that "the
constrained type variables in the declaration may not be generalised".
I think this means that you can't leave the inferred type of k as
"Num a => a", you have to pick a particular numeric type a.
Then Rule 2 says that if you haven't managed to choose a particular
numeric type a by the time you've done your type inference for an
entire module, you have to pick a default type.
So this explains why Hugs thinks that the type of k is Integer if I
load the code in from a separate file (module). However, Hugs is too
eager to resolve the type of k and doesn't apply rule 2 correctly -
hence, if I were to attempt to use k in a way that would bind it to
Int in the module, Hugs would give a type error (incorrectly) because
it would have already bound k to Integer.
In contrast, if I use a let clause, Hugs gets this right, and
resolves the type of k appropriately.
OK - so far so good I hope. What I don't understand though is why the
monomorphism restriction is necessary for the case of a simple
constant declaration. The language manual gives two motivations,
neither of which seems to apply. The first reason is to do with
preventing computations being unexpectedly repeated, but there is no
computation involved here, since k is defined as a constant. The
second reason is to prevent ambiguity, but the example involves a non-
simple binding. So why is it necessary to give a named constant a
monomorphic type, when the unnamed constant has a polymorphic type?
On 20 Sep 2006, at 18:37, Christian Sievers wrote:
> Robert Stroud wrote:
>> However, I still think there's a bit of an inconsistency here. I
>> understand that if k had the type "Num a => a", then the expression
>> "show k" would be ambiguous, but unless I write that expression,
>> there's no ambiguity...
> Actually, you can give k that type, and thanks to defaulting you
> can then still use show k.
>> So it seems to me that the type checker is being a bit too eager to
>> prevent something that hasn't happened yet.
> Here it is the monomorphism restriction (Haskell report section 4.5.5)
> that enforces defaulting.
>> In contrast, in the case where I write "let k = 2 ...", the type
>> checker seems happy to resolve the polymorphic type within the
>> context of the let expression, and does what I expect.
> I hope my last mail explained this: defaulting for monomorphic types
> happens quite late.
>> So is the problem that the context is effectively unbounded when I
>> load the definition from a file, and hence the type checker has to be
>> very conservative about preventing the ambiguity?
> A file is (essentially) a module. This defaulting happens
> "when type inference for an entire module is complete"
> (rule 2 of the above mentioned section), because we don't
> want types to depend on arbitrary other modules - think of
> seperate compilation.
>> I'm afraid I'm also still not clear about why 2 doesn't default to
>> 2::Integer in the same way that k defaults to k::Integer,
> It does, that's why show 2 works.
> Hope that helps
> Christian Sievers
> Haskell mailing list
> Haskell at haskell.org
More information about the Haskell