Opened 5 years ago

Closed 4 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 5 years ago by igloo

difficulty: Unknown
Resolution: wontfix
Status: newclosed

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

comment:2 Changed 5 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 5 years ago by Mathnerd314

Resolution: wontfix
Status: closednew
Summary: Conflicting definitions error for simple variable with guardsUnify patterns and function bindings
Type: bugfeature 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 5 years ago by igloo

Milestone: 7.8.1

comment:5 Changed 4 years ago by simonmar

Resolution: wontfix
Status: newclosed

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.