
#8582: Record syntax for pattern synonyms -------------------------------------+------------------------------------- Reporter: cactus | Owner: mpickering Type: feature request | Status: new Priority: high | Milestone: 8.0.1 Component: Compiler | Version: Resolution: | Keywords: | PatternSynonyms Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: 5144 | Blocking: Related Tickets: | Differential Revisions: Phab:D1152 -------------------------------------+------------------------------------- Comment (by mpickering): I think the confusion here is that pattern synonyms is an undescriptive name for the feature. I prefer to think of (bidirectional) pattern synonyms as data constructors which are not (yet) associated with a particular type. It is better then to say that instead of "In general, a pattern synonym should behave exactly like its expansion." that "In general, a pattern synonym should behave exactly like the relevant data constructor". For example, a bidirectional prefix pattern synonym should behave like a prefix data constructor, an infix pattern synonym should behave like an infix data constructor and a record pattern synonym should behave like a record data constructor. When we introduce records the expansion idea falls apart a bit. For normal prefix pattern synonyms there is one way to pattern match and one way to construct (which matches the expansion). With records there are a few ways to pattern match, a few ways to construct and also the possibility to update. This means the syntax has to diverge from the expansion idea as which expansion do we choose? If we define a synonym `P` and datatype `Q` as follows, {{{#!hs pattern MkP :: Int -> Int -> Q pattern MkP{x, y} = MkQ x1 y1 data Q = MkQ { x1 :: Int, y1 :: Int } }}} then we expect `MkP` to behave precisely as `MkQ` modulo field naming. To be clear these situations are as follows. * Construction (`MkP 0 0`) * Construction with record syntax (`MkP { x = 0, y = 1 }`) * Matching (`foo (MkP c l) = ...`) * Matching with normal record syntax (`foo (MkP {x = l, y = c}) = ...`) * Matching with field puns (`foo (MkP {x, y}) = ...`) * Updating with record syntax (`(MkP 0 0) { x = 1 }`) * Using record selectors (`x (MkP 0 0)`) For a unidirectional synonym, we define selectors and the matching part but not updates or construction. Is that clearer? I think the best specification for this feature is in terms of ordinary records as the goal is to get as close as possible to normal record data constructors. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8582#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler