
#8581: Pattern synonym used in an expression context could have different constraints to pattern used in a pattern context -------------------------------------+------------------------------------- Reporter: cactus | Owner: (none) 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 AntC): Replying to [comment:51 AntC]:
Pattern synonym used in an expression context could act as a smart constructor; and be used in a pattern context just for matching.
Ah, I see I can already do that. But that wasn't at all clear from the docos. So ignore comment:51, here's some notes to improve [https://downloads.haskell.org/~ghc/8.2.1/docs/html/users_guide/glasgow_exts.... #pattern-synonyms the User Guide] -- which mentions a wiki page, but I can't find that. Does it mean the implementation notes linked from comment:24? To make a smart constructor: {{{ data Dumb = Dumb Int pattern Smart { nonneg } <- Dumb nonneg where Smart nonneg = if nonneg >= 0 then (Dumb nonneg) else error "Smart constructor called on negative" }}} Things I noticed: * The User Guide syntax for explicit bidirectionals is not quite right: it says the lhs's are both `pat_lhs`, but you can only use Record syntax on the first line with `<-`; the second line with `=` must use Prefix or Infix. * You can put an arbitrary `expr` on rhs of the `=`. The User Guide says that, but gives no examples other than Data constructors. * On the rhs of `=`, the pattern/constructor doesn't have to be the same as on the `<-` line. Indeed you can go {{{ data PosNeg = Pos Int | Neg Int pattern Smarter{ nonneg } <- Pos nonneg where Smarter x = if x >= 0 then (Pos x) else (Neg x) }}} And I guess that possibility is why you can't use Record syntax on lhs of the `=`: you don't know which combo of field names applies until you know which data constructor you're producing. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8581#comment:52 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler