
#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