Note [Arrow parsing mode]
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
- Ambiguous syntactic categories GHC.Parser.PostProcess
Referenced by 3
- GHC.Parser.PostProcess call site ×3