Ticket #7676 (new feature request)

Opened 3 months ago

Last modified 6 weeks ago

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 Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

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

Changed 3 months ago by igloo

  • status changed from new to closed
  • difficulty set to Unknown
  • resolution set to wontfix

Thanks for the report. However, this matches the behaviour specified by the report; see  http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-830004.4.3 for details.

Changed 3 months ago by guest

Note that this is not specific to guards.

f = 0     -- error
f = 0

g _ = 0   -- correct
g _ = 0

Changed 3 months ago by Mathnerd314

  • status changed from closed to new
  • type changed from bug to feature request
  • resolution wontfix deleted
  • summary changed from Conflicting definitions error for simple variable with guards to Unify patterns and function bindings

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  http://hackage.haskell.org/trac/haskell-prime/wiki/SpecifyPatternBindingSemantics 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.

Changed 6 weeks ago by igloo

  • milestone set to 7.8.1
Note: See TracTickets for help on using tickets.