#9110 closed bug (fixed)

MonomorphismRestriction too eager

Reported by: goldfire Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.8.2
Keywords: Cc: daniel@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):


This strange example came up on IRC:

{-# LANGUAGE MonoLocalBinds, MonomorphismRestriction #-}

foo :: a
foo = bar

bar = undefined where
	_ = baz undefined

baz = const [1]


    Couldn't match expected type ‘a’ with actual type ‘t0’
      because type variable ‘a’ would escape its scope
    This (rigid, skolem) type variable is bound by
      the type signature for foo :: a
      at /Users/rae/temp/Bug.hs:3:8
    Relevant bindings include
      foo :: a (bound at /Users/rae/temp/Bug.hs:4:1)
    In the expression: bar
    In an equation for ‘foo’: foo = bar

Setting either NoMonoLocalBinds or NoMonomorphismRestriction fixes the problem. After some staring at this, I didn't get to the bottom of it. But I did learn some things:

  • If we remove the definition for foo, the module compiles.
  • With the monomorphism restriction (MR), bar gets the type GHC.Exts.Any.
  • Without the MR, bar gets the type forall t.t.
  • The MR bites baz, as it should.

According to the rules in the Haskell Report, it seems that the MR should not bite bar, as bar's inferred type's unification type variable is not constrained -- this is why I'm posting the example as a bug.

But, I may be entirely mistaken, as the whole example makes my brain go a little fuzzy. In particular, I'm a little mystified how MonoLocalBinds enters the picture, but it is necessary to tickle the problem. Apologies if GHC is behaving correctly here.

Change History (4)

comment:1 Changed 17 months ago by dmwit

  • Cc daniel@… added

comment:2 Changed 17 months ago by simonpj

Here is what is happening:

  • baz gets the type forall b. b -> alpha, where alpha is a unification variable, plus a Num alpha constraint. The MR prevents us generalising the alpha.
  • Because baz is bitten by the MR, it is not considered "closed"; see in the user manual. Actually the user manual is badly framed here. It should say "A binding is considered closed if (a) all its free variables are imported or closed, and (b) it is unaffected by the monomorphism restriction."
  • Because baz is not closed, and bar mentions baz, bar is not closed. Since LocalMonoBinds is force, bar is not generalised.
  • Since bar is not genrealised, foo really is not as polymorphic as its type signature claims.

I'll fix the user manual, but otherwise things are working fine


comment:3 Changed 17 months ago by goldfire

Ah. I was thinking that the MonoLocalBinds was affecting the of the where-bound _ and that somehow that was causing the problem, hence my deep confusion in that area. Your explanation makes good sense. Thanks.

comment:4 Changed 17 months ago by simonpj

  • Resolution set to fixed
  • Status changed from new to closed

User manual improvement:

commit 3a61e6de311ad235aec9f0a55201656805e3c04e
Author: Simon Peyton Jones <[email protected]>
Date:   Fri May 16 08:34:44 2014 +0100

    Tighten up wording in the section on let-generalisation and MonoLocalBinds

 docs/users_guide/glasgow_exts.xml |   49 ++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 14 deletions(-)
Note: See TracTickets for help on using tickets.