[GHC] #8581: Pattern synonym used in an expression context could have different constraints to pattern used in a pattern context
GHC
ghc-devs at haskell.org
Sat Jul 23 18:30:13 UTC 2016
#8581: Pattern synonym used in an expression context could have different
constraints to pattern used in a pattern context
-------------------------------------+-------------------------------------
Reporter: cactus | Owner:
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler | Version:
Resolution: | Keywords:
| PatternSynonyms
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
While we're at this, there is another outstanding issue: a pattern synonym
type should give some indication of the synonym's directionality.
I think there are two quite separable questions here:
1. What features do we want GHC to support?
2. What concrete syntax will support those features?
Let's tackle these design questions in order.
For (1) the fundamental question seems to be:
1a. What relationship between the expression-type and the pattern-type do
we wish to require?
Possible answers:
A. None at all.
B. The types have the same structure, but perhaps different constraints.
C. Something in between. For example, both have to have the same arity
and/or the same head of the result type.
Personally, I think only A or B is defensible here. Furthermore, I favor
A. History has shown that Haskellers like as much freedom to explore as
possible. There is no type safety issue at hand. So let's give people more
rope. I wager the idea of one symbol having two different types (in two
very-easy-to-distinguish contexts) is less confusing than, say, kind
polymorphism.
Now, onto design point (2). I wonder if it's helpful to think of pattern
synonym types as a `(PatternType, Maybe Type)`. The first component is a
pattern-type, with its separate provided and required contexts, etc. It
classifies the pattern synonym when used as a pattern. The second
component is (perhaps) the type of the pattern synonym when used as an
expression. This component is missing, naturally, when the synonym is
unidirectional. Note that this component (when it exists) is just a normal
type.
Typically, the second component can be constructed in a straightforward
manner from the first (if the synonym is bidirectional). But it need not
be.
Thinking along these lines, I propose the following rules for syntax:
1. `pattern <Pat> :: <PatternType>`, when written outside of a `-boot`
file, sets the first component of the type. It also sets the second
component of the type when there is no separate type signature for `<Pat>`
and when the pattern is declared to be bidirectional.
2. `<Pat> :: Type` can be written to set the second component of a pattern
synonym type.
3. In a `-boot` file, a `pattern <Pat> :: <PatternType>` sets only the
first component of a pattern synonym type. If you want a bidirectional
pattern synonym, write two signatures.
Note that point (2) creates something like a top-level signature (the kind
we use all the time when defining functions) but for a capitalized (or
`:`-prefixed) identifier. As far as I can tell, this is a new spot in the
grammar (ignoring "naked" top-level declaration splices that consist of
one identifier followed by a type annotation, which conflict with normal
type signatures, anyway).
What do we think? Please consider addressing design point (1) separately
from design point (2), as I think that will simplify the discussion.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8581#comment:38>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list