Parentheses in Haskell: where/why are they forbidden on LHS of a decl

Viewed 84

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'
0 Answers
Related