I'm used to parentheses in Haskell being mostly optional: they're needed to override the usual binding/precedence; otherwise freely add/omit them to aid readability. Then consider these (at GHC 8.6.5.):
f (Just x) = x -- needed around `(Just x)` because `f Just x` would bind differently
(Just y) = Just () -- pattern based binding for var `y`
Just y2 = Just () -- but optional around `(Just y)`
Just (y3) = Just () -- optional around bare variables
x = ()
(x2) = ()
Without trying it first, do you expect parens would be optional around the LHS of a function equation here:
(f (Just x)) = x
That's rejected: Parse error in pattern: f. "in pattern" suggests that the parser expects ( to start a pattern, then why isn't the pattern Just y2 = ... rejected because no parens?
Something inconsistent/a little weirder happens with
{-# LANGUAGE PatternSynonyms #-}
pattern MkJust x = Just x -- OK
-- pattern M2Just (x) = Just x -- parse error on input `('
-- pattern (M3Just x) = Just x -- parse error on input `M3Just'
Is there some rationale/logic/(um) pattern to the parens with these examples?
I'm asking because I always write patterns in parens (Just y) = ...; I was surprised the parens were optional because Just y2 = ... could easily be a typo for a function decl just y2 = ....
Addit: Ah yes, parens are required around an operator used prefix. These work:
pattern (::~~) x y = (x, y) -- OK
pattern x ::~ y = (x, y) -- OK
(::~~) True y4 = (True, ()) -- OK
(True ::~~ y5) = (True, ()) -- OK
True ::~~ y6 = (True, ()) -- OK
This doesn't
-- pattern (x ::~~ y) = (x, y) -- parse error on input `x'