Note [PatBuilder]
Unlike HsExpr or HsCmd, the Pat type cannot accommodate all intermediate forms,
so we introduce the notion of a PatBuilder.
Consider a pattern like this:
Con a b c
We parse arguments to "Con" one at a time in the fexp aexp parser production,
building the result with mkHsAppPV, so the intermediate forms are:
1. Con
2. Con a
3. Con a b
4. Con a b c
In 'HsExpr', we have 'HsApp', so the intermediate forms are represented like
this (pseudocode):
1. "Con"
2. HsApp "Con" "a"
3. HsApp (HsApp "Con" "a") "b"
3. HsApp (HsApp (HsApp "Con" "a") "b") "c"
Similarly, in 'HsCmd' we have 'HsCmdApp'. In 'Pat', however, what we have
instead is 'ConPatIn', which is very awkward to modify and thus unsuitable for
the intermediate forms.
We also need an intermediate representation to postpone disambiguation between
FunBind and PatBind. Consider:
a `Con` b = ...
a `fun` b = ...
How do we know that (a `Con` b) is a PatBind but (a `fun` b) is a FunBind? We
learn this by inspecting an intermediate representation in 'isFunLhs' and
seeing that 'Con' is a data constructor but 'f' is not. We need an intermediate
representation capable of representing both a FunBind and a PatBind, so Pat is
insufficient.
PatBuilder is an extension of Pat that is capable of representing intermediate
parsing results for patterns and function bindings:
data PatBuilder p
= PatBuilderPat (Pat p)
| PatBuilderApp (LocatedA (PatBuilder p)) (LocatedA (PatBuilder p))
| PatBuilderOpApp (LocatedA (PatBuilder p)) (LocatedA RdrName) (LocatedA (PatBuilder p))
...
It can represent any pattern via 'PatBuilderPat', but it also has a variety of
other constructors which were added by following a simple principle: we never
pattern match on the pattern stored inside 'PatBuilderPat'. References 0
This Note does not link to any other.
Referenced by 3
- GHC.Parser.Types call site ×2
- Ambiguous syntactic categories GHC.Parser.PostProcess