Opened 14 months ago

Closed 7 months 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 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 (5)

comment:1 Changed 14 months 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 http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-830004.4.3 for details.

comment:2 Changed 14 months ago by guest

Note that this is not specific to guards.

f = 0     -- error
f = 0

g _ = 0   -- correct
g _ = 0

comment:3 Changed 14 months 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 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.

comment:4 Changed 12 months ago by igloo

  • Milestone set to 7.8.1

comment:5 Changed 7 months 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.