Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,969
    • Issues 4,969
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 473
    • Merge requests 473
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Wiki
  • pattern synonyms

pattern synonyms · Changes

Page history
Edit PatternSynonyms authored Oct 29, 2015 by Matthew Pickering's avatar Matthew Pickering
Hide whitespace changes
Inline Side-by-side
pattern-synonyms.md
View page @ f89d2e8c
......@@ -462,108 +462,7 @@ As a nice collateral win this proposal handles `pattern Name name <- Person name
## Record Pattern Synonyms
Normal pattern synonyms provide a convenient way to abstract away from ADTs by explicitly defining the meaning of the pattern and the ability to define the constructor.
Currently there is no way to similar way to project an existing datatype to a record.
Adding this feature provides completeness as pattern synonyms would become equally expressive as ordinary data type declarations.
### Specification
The syntax for defining pattern synonyms is extened as follows
```wiki
patsyndecl_w_records ::= patsyndecl
| 'pattern' con '{' var1 ',' ... ',' varn '}' <- pat
```
A bidirectional record pattern synonym `P` with type `T` and arguments `f1, f2, ..., fn` which have types `t1, t2, ...., tn` should behave just as if `P` had been defined as a record constructor for `T` with the corresponding fields.
For example,
```wiki
data T ... = ... | P { f1 :: t1, f2 :: t2, ..., fn :: tn }
```
### Design
The proposed syntax is as follows
```wiki
pattern Foo{bar, baz} = (bar, baz)
```
which overloads the syntax for named field puns.
If a unidirectional pattern is declared then the pattern along with record selectors are provided. The following five definitions are equivalent.
```wiki
getFst1 Foo{bar} = bar
getFst2 Foo{bar=qux} = qux
getFst3 Foo{..} = bar
getFst4 (Foo v _) = v
getFst5 v = bar v
```
When a bidirectional synonym is declared then the constructor `Foo` is also declared which can be used in two ways.
```wiki
myFoo = Foo "first" 2
hisFoo = Foo { bar = "first", baz = 2 }
```
Finally we consider record updates.
```wiki
updateBaz x = x {baz = 6}
```
An unresolved design point is how record updates should be handled. Given Foo is in scope then there is an unambiguous type for this expression (as baz is uniquely a selector for `Foo`). Thus the inferred type of `updateBaz` would be `updateBaz :: (a, b) -> (Int, b)`.
This whole construct seems quite strange as it would also seem possible to write (the currently illegal) `(1,2) {baz = Just 6}` as well as `(Foo 1 2) { baz = Just 6}`. Currently pattern synonyms do not change the semantics of programs outside from the explicit use of the synonym. This example is slightly different as we do not use `Foo` but merely the field name `baz`. I am not sure whether this would be confusing to users.
### Tricky bits
- There is now a potential ambiguity.
```wiki
data D = MkD { foo :: Int }
pattern Pat = MkD { foo = Int }
baz = Pat { foo = 5 }
```
>
> Here, I'm intending `Pat { foo = 5 }` to be a record *update*, not a record *construction*. But it's confusing! Does this work?
#### Answer
Not currently - `baz` is parsed as a `RecordCon` which then fails as `Pat` is not a constructor with field `foo`.
- Import/export syntax has to be extended to accommodate the field labels. So, if we have
```wiki
pattern Pat { a } = Just a
```
>
> then we should be able to write any of the following in an export list: `pattern Pat`, `pattern Pat(..)`, `pattern Pat(a)`. (The last two mean the same thing.) It would only be logical to extend this syntax to also allow record data constructors to operate the same way. Question: should record data constructors be allowed to use this syntax when exported without the `pattern` keyword?
See [PatternSynonyms/RecordPatternSynonyms](pattern-synonyms/record-pattern-synonyms)
## Associating synonyms with types
......
Clone repository Edit sidebar
  • 9.6
  • Adventures in GHC compile times
  • All things layout
  • AndreasK
  • AndreasPK
  • Back End and Run Time System
  • Backpack refactoring
  • Backpack units
  • Brief Guide for Compiling GHC to iOS
  • Building GHC on Windows with Stack protector support (SSP) (using Make)
  • CAFs
  • CafInfo rework
  • Compiling Case Expressions in ghc
  • Compiling Data.Aeson Error
  • Contributing a Patch
View All Pages