Note [Arrow parsing mode]

GHC/Parser/PostProcess.hs:2229 compiler

Consider this example:
  f (K (a -> b)) = ()

A pattern of the form (a -> b) could be parsed in one of two ways:
  * a view pattern `viewfn -> pat` (with ViewPatterns)
  * a function type `t1 -> t2`     (with RequiredTypeArguments)

This depends on the enabled extensions:
  NoViewPatterns, RequiredTypeArguments     =>  function type
  NoViewPatterns, NoRequiredTypeArguments   =>  error (suggest ViewPatterns)
  ViewPatterns,   RequiredTypeArguments     =>  view pattern
  ViewPatterns,   NoRequiredTypeArguments   =>  view pattern

The decision how to parse arrow patterns (p1 -> p2) is captured by the
`ArrowParsingMode` data type, produced in `withArrowParsingMode` and
consumed in `mkHsArrowPV`.

Naively, one might expect to see the following definition:

  a simple (but insufficient) definition
  data ArrowParsingMode = ArrowIsViewPat | ArrowIsFunType

However, there is a slight complication that leads us to parameterize these
constructor with GADT type indices. In a pattern (p1 -> p2), what is the AST
type to represent the LHS `p1`? It depends:
  * if (p1 -> p2) is a view pattern,  `p1` is an HsExpr
  * if (p1 -> p2) is a function type, `p1` is a  Pat (PatBuilder)

And since the decision how to parse `p1` depends on the arrow parsing mode, we
could try to encode the LHS type as a GADT index:

  a less simple (but still insufficient) definition
  data ArrowParsingMode lhs where
    ArrowIsViewPat :: ArrowParsingMode (PatBuilder GhcPs)
    ArrowIsFunType :: ArrowParsingMode (HsExpr GhcPs)

This definition would suffice for parsing patterns, but remember that
expressions, commands, and patterns are all parsed using a unified framework
`DisambECP`, as described in Note [Ambiguous syntactic categories].

In an expression (e1 -> e2), the LHS is always represented by an HsExpr.
We can account for this with a further refinement of the definition:

  actual definition
  data ArrowParsingMode lhs rhs where
    ArrowIsViewPat :: ArrowParsingMode (HsExpr GhcPs) b
    ArrowIsFunType :: ArrowParsingMode b b

So when parsing a view pattern, the LHS is an HsExpr; and when parsing a
function type, the type of the LHS is assumed to match the type of the RHS,
which works out just right both for expressions and patterns.

References 1

Referenced by 3