ImplicitParams and MonoLocalBinds

Simon Peyton-Jones simonpj at
Wed Apr 3 19:43:44 CEST 2013

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.


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 papers<> "Let should not be generalised" and "Modular type inference with local assumptions", and a related blog post<>.
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 at [mailto:glasgow-haskell-users-bounces at] On Behalf Of Iavor Diatchki
Sent: 29 March 2013 00:07
To: Roman Cheplyaka
Cc: GHC Users Mailing List
Subject: Re: ImplicitParams and MonoLocalBinds


Aha! This page explains what is going on:

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`.


On Thu, Mar 28, 2013 at 4:39 PM, Iavor Diatchki <iavor.diatchki at<mailto:iavor.diatchki at>> wrote:
This does not appear to be related to ImplicitParameters, rather `MonoLocalBinds` is not working as expected.

Here is an example without implicit parameters that compiles just fine, but would be rejected if `p` was monomorphic:

{-# LANGUAGE NoMonomorphismRestriction, MonoLocalBinds #-}

class C a where
  f :: a -> ()

instance C Bool where f = const ()
instance C Char where f = const ()

g = let p = f
    in (p 'a', p True)


On Fri, Mar 22, 2013 at 1:39 AM, Roman Cheplyaka <roma at<mailto:roma at>> wrote:
The value of the following expression

  let ?y = 2  in
  let  p = ?y in
  let ?y = 1  in

depends on whether the second binding is generalised.

MonomorphismRestriction makes it not generalise, hence the value is 2.

What surprises me is that MonoLocalBinds doesn't have this effect.

  Prelude> :set -XImplicitParams -XNoMonomorphismRestriction -XMonoLocalBinds
  Prelude> let ?y = 2 in let p = ?y in let ?y = 1 in p

What's going on here?


Glasgow-haskell-users mailing list
Glasgow-haskell-users at<mailto:Glasgow-haskell-users at>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Glasgow-haskell-users mailing list