Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#1901 closed merge (fixed)

6.8.1 incorrectly infers contexts from pattern matches.

Reported by: guest Owned by: igloo
Priority: normal Milestone:
Component: Compiler Version: 6.8.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


The following code is rejected by GHC 6.6.1

data Foo a = (Num a) => MkFoo a

data (Num a) =>  Foo' a =  MkFoo' a

data Foo'' a =
    (Num a) => X a
  | (Show a) => Y a 

fun :: Foo'' t -> String
fun (Y a) = show a

-- Prelude> :load "/Users/jules/personal/progs/test.hs"
-- [1 of 1] Compiling Main             ( /Users/jules/personal/progs/test.hs, interpreted )

-- /Users/jules/personal/progs/test.hs:10:12:
--     No instance for (Show t)
--       arising from use of `show'
--       at /Users/jules/personal/progs/test.hs:10:12-17
--     Possible fix: add (Show t) to the type signature(s) for `fun'
--     In the expression: show a
--     In the definition of `fun': fun (Y a) = show a
-- Failed, modules loaded: none.

According to the GHC manual (section 8.4.5) this rejection is correct. That is, haskell98 is not supposed to infer contexts from a pattern match. However strange that behaviour is, it is apparently the standard.

6.8.1 appears to do the more natural, but incorrect, thing, and accept this program.

Change History (7)

comment:1 Changed 9 years ago by simonpj

difficulty: Unknown
Resolution: invalid
Status: newclosed

It's right for this program to be accepted. Foo'' uses a GHC extension, namely contexts on individual data constructors, which is syntactic sugar for the GADT-style declaration. It's not Haskell 98.

If you instead use the Haskell 98 type Foo', and try this

fun :: Foo' t -> t
fun (MkFoo' a) = a+1

you get the Haskell 98 behaviour.

    Could not deduce (Num t) from the context ()
      arising from a use of `MkFoo'' at Foo.hs:6:5-12
    Possible fix:
      add (Num t) to the context of the type signature for `fun'
    In the pattern: MkFoo' a
    In the definition of `fun': fun (MkFoo' a) = a + 1 

I'll improve the user manual.

comment:2 Changed 9 years ago by guest

OK. I would submit that the section of the user manual I pointed to is confusing, then, because it certainly gives the impression that it's valid haskell98 :)

However, bearing that in mind, shouldn't the program be rejected unless some appropriate extension is turned on?

comment:3 Changed 9 years ago by simonpj

Resolution: invalid
Status: closedreopened
Type: bugmerge

Aha, that's an excellent point. When compiling this declaration

data Foo a = (Num a) =>  MkFoo a

the HEAD now says

    Data constructor `MkFoo' has existential type variables, or a context, or both
      (Use -XExistentialQuantification or -XGADTs to allow this)
    In the data type declaration for `Foo'

Ian, if you feel like adding a test case it might (just) be worth it.

The patch (which I'm validating now) is this:

Fri Nov 16 14:56:09 GMT 2007
  * FIX Trac #1901: check no existential context in H98 mode

comment:4 Changed 9 years ago by simonpj

Owner: set to igloo
Status: reopenednew

comment:5 Changed 9 years ago by igloo

Resolution: fixed
Status: newclosed


comment:6 Changed 8 years ago by simonmar

Architecture: UnknownUnknown/Multiple

comment:7 Changed 8 years ago by simonmar

Operating System: UnknownUnknown/Multiple
Note: See TracTickets for help on using tickets.