Opened 4 years ago

Closed 3 years ago

#7676 closed feature request (wontfix)

Unify patterns and function bindings

Reported by: Mathnerd314 Owned by:
Priority: normal Milestone: 7.8.1
Component: Compiler Version: 7.7
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


The following program:

a | True = 1
a | False = 2

produces an error (on 7.4.1 and 7.7.2012117):

Conflicting definitions for 'a'

The following two examples produce no error:

b | True = 1
  | False = 2

c _ | True = 1
c _ | False = 2

I would expect a, b. and c () to have identical behaviour.

Change History (5)

comment:1 Changed 4 years ago by igloo

  • difficulty set to Unknown
  • Resolution set to wontfix
  • Status changed from new to closed

Thanks for the report. However, this matches the behaviour specified by the report; see for details.

comment:2 Changed 4 years ago by guest

Note that this is not specific to guards.

f = 0     -- error
f = 0

g _ = 0   -- correct
g _ = 0

comment:3 Changed 4 years ago by Mathnerd314

  • Resolution wontfix deleted
  • Status changed from closed to new
  • Summary changed from Conflicting definitions error for simple variable with guards to Unify patterns and function bindings
  • Type changed from bug to feature request

Ah, so I am really filing a feature request! I propose an extension which changes the grammar to be as follows:

decl 	→ 	funlhs rhs

funlhs 	→ 	pat { apat }
	| 	pat varop pat
	| 	( funlhs ) { apat }

apat 	→ 	funlhs
	| 	var [ @ apat]
	| 	...

I think this introduces a small amount of ambiguity in the grammar (funlhs → pat → lpat → apat → funlhs), but it should be easy to transform the grammar so as to avoid it.

Note that your definition for g, although not rejected outright by GHC, does produce a warning that "Pattern matches are overlapped." I think such a warning would suffice for f as well. There is nothing in the report specifying that multiple pattern bindings MUST give an error; instead, it is mute on the subject. It does not even specify the semantics of single pattern bindings very clearly, as the (implemented but still unaccepted?) proposal shows.

This grammar allows convenient definitions such as the following (adapted from the numbers package)

(x < y, x > y) = (<0) &&& (>0) $ s' (digitsToBits digits) where (CR s') = x-y

desugared as follows:

z x y = (<0) &&& (>0) $ s' (digitsToBits digits) where (CR s') = x-y
x > y = case (z x y) of { (x < y, x > y) -> (x > y) }
x < y = case (z x y) of { (x < y, x > y) -> (x < y) }

The case expression should perhaps be desugared a bit more so the semantics are clear:

case (z x y) of { (a,b) -> let { (x < y) = a; (x > y) = b } in ... }

If you think this is too mind-bending to be useful, I suppose the syntax could be restricted a bit; but I find the generality to be rather pretty.

comment:4 Changed 4 years ago by igloo

  • Milestone set to 7.8.1

comment:5 Changed 3 years ago by simonmar

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

I think this feature request is unlikely to make any progress on this ticket. The best way is to start with discussion on the mailing lists, and then if it seems feasible flesh out the design on a wiki page.

Note: See TracTickets for help on using tickets.