
Correct. Maybe the flag should be called “MonoOpenBinds”!
Really, the simplest solution is to write a type signature. Then all is clear.
I’m very open to adding something to the documentation to explain about this. The current section is below... concrete suggestions for improvement would be welcome.
Simon
7.12.10. Let-generalisation
An ML-style language usually generalises the type of any let-bound or where-bound variable, so that it is as polymorphic as possible. With the flag -XMonoLocalBinds GHC implements a slightly more conservative policy: it generalises only "closed" bindings. A binding is considered "closed" if either
* It is one of the top-level bindings of a module, or
* Its free variables are all themselves closed
For example, consider
f x = x + 1
g x = let h y = f y * 2
k z = z+x
in h x + k x
Here f and g are closed because they are bound at top level. Also h is closed because its only free variable f is closed. But k is not closed because it mentions x which is locally bound. Another way to think of it is this: all closed bindings could be defined at top level. (In the example, we could move h to top level.)
All of this applies only to bindings that lack an explicit type signature, so that GHC has to infer its type. If you supply a type signature, then that fixes type of the binding, end of story.
The rationale for this more conservative strategy is given in the papershttp://research.microsoft.com/%7Esimonpj/papers/constraints/index.htm "Let should not be generalised" and "Modular type inference with local assumptions", and a related blog posthttp://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7.
The flag -XMonoLocalBinds is implied by -XTypeFamilies and -XGADTs. You can switch it off again with -XNoMonoLocalBinds but type inference becomes less predicatable if you do so. (Read the papers!)
From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] On Behalf Of Iavor Diatchki
Sent: 29 March 2013 00:07
To: Roman Cheplyaka
Cc: GHC Users Mailing List
Subject: Re: ImplicitParams and MonoLocalBinds
Hi,
Aha! This page explains what is going on: http://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7
The summary is that the definition of what is "local" is not what one might expect: only things that depend
on variables in scope are considered to be locals, other bindings, that could be lifted out (e.g., like `p` in both examples)
are not considered local and are generalized. Of course, with implicit parameters this is not what one might hope for...
A while back there was a discussion about adding a construct for monomorphic bindings to the language (I think the proposed notation was something like "x := 2").
Perhaps we should revisit it, it seems much simpler than the rather surprising behavior of `MonoLocalBinds`.
-Iavor
On Thu, Mar 28, 2013 at 4:39 PM, Iavor Diatchki