Indeed, it's possible to parse simple grammar for (even nested) patterns without parens at all. Suppose such one:
<PAT> ::= <WILDCARD> | <VAR> | <CON0> | <CON1> <PAT> | <CON2> <PAT> <PAT> ...
<VAR> ::= <LNAME>
<CON*> ::= <UNAME>
<WILD> ::= "_"
where LNAME is names that starts with lowercase letter and UNAME starts with uppercase letter. While parsing we should look up constructor name so we can find out its arity. Then we can parse constructor fields using arity information. But this lookup might significant complicate and slow down parsing itself. Haskell has much more complex patterns(view patterns, "as" patterns, records, infix constructors with arbitrary fixity, e.t.c.) and omitting parens can lead to ambiguity.
Though there is another reason not to do that. Consider the following code:
data Bar = Bar Int
data Foo = Foo Int
libFunction Foo a Bar b = a + b
someUse bar foo = libFunction foo bar
Next imagine we change datatypes a bit:
data Bar = Bar
data Foo = Foo Int Bar Int
Modified code might still typecheck, but the function will do not that we expect. Not a real world example but nevertheless. And since Haskell have type classes it can be pretty hard to find out where we get something wrong.
In other words: we can loose quality of error messages and parens defends us from unexpected behaviour after changes.