Christian,

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?

Thanks,

Robert


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@haskell.org
http://www.haskell.org/mailman/listinfo/haskell

_______________________________________________
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell

Reply via email to