
#11367: [Regression] Only one clause allowed in (explicitly bidirectional) pattern synonyms -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.1 Resolution: | Keywords: | PatternSynonyms Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Iceland_jack): Replying to [comment:8 simonpj]:
Well in normal code you can't write {{{ f :: Int -> Int }}} and omit the declaration of `f`. You have to write {{{ f :: Int -> Int f = undefined }}} So it's consistent to require the same for pattern synonyms. Funny you bring that up! I'm not sure if it's by design or a regression but omitting a method declaration (GHC 7.10) used to give a warning: {{{ Prelude> :set -XInstanceSigs Prelude> class A a where f :: a Prelude> instance A Int where f :: Int
<interactive>:11:10: Warning: No explicit implementation for ‘f’ In the instance declaration for ‘A Int’ }}} while in 8.1: {{{ <interactive>:3:22: error: The class method signature for ‘f’ lacks an accompanying binding (The class method signature must be given where ‘f’ is declared) }}} which [https://xkcd.com/1172/ affects me similarly]: I usually turn off warnings while churning out code and turn them on afterwards, now one must write a dummy definition "f = undefined" (maybe it's not so silly to expand standalone type signatures ⸨top-level, where block, instance⸩ into a dummy declaration: `-fcut-me-some-slack`....)¹
For my money, I think it's maybe a mistake for the unidirectional/bidirectional split to be so quietly signaled. One could imagine {{{ pattern unidirectional Q a = pat pattern bidirectional P a b = pat pattern bidirectional R x = pat where R = ... }}} But opinions vary.
May be! I feel it plays into the usual duality between reading and writing code. Your suggestion would certainly be clearer to people unfamiliar with pattern synonyms and all the different variations thereof, make it easier to search for and `grep` code. Consider my [comment:5 response to mpickering] as an offhand remark — a data point. It certainly should not dictate any design decisions.
Usually `where` clauses contain zero or more bindings, which is why an empty `where` is usually ok. But here it must contain exactly one. (Two would not make sense either.)
Could you not view a `where` clause in a pattern synonym as containing zero bindings (unidirectional) or a single binding (explicitly bidirectional). ¹ The more I think about it the less objectionable it sounds, as a flag solely for development. It's common to write stubs in Haskell given only their type with an dummy definition to satisfy the compiler, the compiler could expand `getId :: Person -> Id` into {{{#!hs getId :: Person -> Id getId = error "getId:15:1: Not defined." }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11367#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler