Ticket #2187 (closed bug: wontfix)

Opened 1 year ago

Last modified 9 months ago

Top-level bindings are broken for polymorphic values

Reported by: yallop Assigned to:
Priority: normal Milestone: 6.10 branch
Component: Compiler Version: 6.8.2
Severity: major Keywords:
Cc: SamB Difficulty: Unknown
Test Case: Operating System: Unknown/Multiple
Architecture: Unknown/Multiple

Description

Top-level pattern bindings don't work for polymorphic values. Here's an example program:

    [x] = [id]

ghci gives this the type

   *Main> :t x
   x :: GHC.Prim.Any -> GHC.Prim.Any

which can't be used

   *Main>  x ()

   <interactive>:1:2:
   Couldn't match expected type `GHC.Prim.Any'
          against inferred type `()'
   In the first argument of `x', namely `()'
   In the expression: x ()
   In the definition of `it': it = x ()

Adding a type signature doesn't help:

   x :: a -> a
   [x] = [id]

   Couldn't match expected type `forall a. a -> a'
          against inferred type `a -> a'
   Probable cause: `id' is applied to too few arguments
   In the expression: id
   In the expression: [id]

Change History

03/30/08 05:42:52 changed by igloo

  • difficulty set to Unknown.
  • milestone set to 6.10 branch.

Thanks for the report. Your first example is deliberately broken (relative to Haskell98); see http://www.haskell.org/ghc/docs/latest/html/users_guide/monomorphism.html for details, or use -XNoMonoPatBinds to get the Haskell98-specified behaviour.

If you give a type signature for x then I would have expected it to work; Simon?

yallop, I assume you ran into this problem in a real program?

03/31/08 02:01:46 changed by yallop

Thanks for the reply. Yes, I ran into the problem in a real program.

I have code that looks like this:

   (x1,...,xn) = (e1,...en)
      where y = e
            z = f

which is generated via Template Haskell. Sometimes the bindings are supposed to be polymorphic, sometimes not.

It looks like I have two choices, neither of which is particularly desirable:

  1. Change the generation scheme to emit less elegant code, which will also complicate the generation code.
  2. Require all users of the library to add -XNoMonoPatBinds

From a user's perspective (at least, from this user's), defaulting to monomorphic pattern bindings looks like quite an unfortunate choice:

  1. It doesn't bring any actual benefits to the user (that I can see).
  2. It breaks compatibility with Haskell 98, so code that works on other implementations mysteriously fails without so much as a warning.
  3. It generates quite unusable code: there's no realistic use for functions of type
            GHC.Prim.Any -> GHC.Prim.Any
    
    so why default to generating that sort of thing?
  4. It makes it more difficult to transform programs, since you can no longer replace
           x = f (a,b)
    
    with
           (c,d) = (a,b)
           f (c,d)
    

It's difficult to see how it can simplify the implementation, since you still have to cope with -XNoMonoPatBinds. There must be *some* reason for this change, but what can it be?

03/31/08 14:04:48 changed by simonmar

Linking to the Haskell' page with the motivation for this change: http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/MonomorphicPatternBindings

As for whether it makes the implementation simpler, I presume the intention was to deprecate and eventually remove -XNoMonoPatBinds at which point the complexities to deal with polymorphic pattern bindings would go away. (however we can't do that while we still want to support Haskell 98, of course). I'm going to follow up on this with the Haskell' committee.

04/12/08 12:20:00 changed by SamB

  • cc set to SamB.

*more* ugly warts? I thought we were trying to get *rid* of those ...

Any bets on which 6.10.x release will revert this?

06/10/08 18:34:03 changed by simonmar

  • status changed from new to closed.
  • resolution set to wontfix.

So GHC is behaving "correctly" here, although for Haskell' we've decided to do things differently; see #2357. Hopefully we'll be able to implement the change for 6.10.1.

09/30/08 08:40:35 changed by simonmar

  • architecture changed from Unknown to Unknown/Multiple.

09/30/08 08:51:45 changed by simonmar

  • os changed from Unknown to Unknown/Multiple.