|Version 2 (modified by 3 years ago) (diff),|
Implementation notes for pattern synonyms
After parsing, and during renaming, pattern synonyms are stored as
During renaming, pattern synonyms are put in recursive binding groups together with function bindings. Other pattern synonyms and ViewPatterns can cause recursive pattern synonym declarations, which are rejected.
The typechecking pass turns
PatSynBinds into a
PatSyn and several
HsBinds. To fill in the
PatSyn, we typecheck the right-hand side
of the pattern synonym declaration, then do some extra processing on
it to reject as-patterns and optionally compute the reverse of the
pattern synonym (for implicitly bidirectional ones). Afterwards, we
collect universal & existential type variables and typeclass dictionary
variables to be used when creating
ConPatOut patterns from pattern
synonym occurances, and generate some
PatSynstores typing information for the pattern synonym, to be consulted when typechecking pattern synonym usage sites.
- The first
HsBindis the binder for the matcher function generated from the pattern synonym. The matcher is used when desugaring pattern synonym usage sites (see below).
- For bidirectional pattern synonyms, another
HsBindcalled a wrapper is created to be used for pattern synonym usages in expression contexts. It is a wrapper in the same sense as a constructor wrapper.
Pattern synonym occurances in patterns are turned into
just like regular constructor matches.
ConPatOut has been changed to
ConLike instead of a
ConLike type is simply
the sum of
During match grouping, subsequent
PatSyn patterns are combined into
one group per pattern synonym. For example, given the following code:
pattern Single x <- [x] pattern Pair x y <- [x, y] f  = 0 f (Single True) = 1 f (Single False) = 2 f (Pair _ _) = 3 f (_:_:_) = 4
Single patterns are put in one
For each pattern synonym, a matcher function is generated which gets a scrutinee and a success and a failure continuations. Given a type
data T a where MkT :: (Cls b) => b -> a -> T a
and a pattern synonym
pattern Pat x y = MkT x y
we generate the matcher function
$mPat :: forall r a. T a -> (forall b. Cls b => b -> a -> r) -> r -> r $mPat scrutinee pass fail = case scrutinee of MkT x y -> pass x y _ -> fail
Occurances of pattern synonyms are then desugared into calls to this matcher function. This allows pattern synonym definitions to be just as opaque as function definitions: their type defines their interface completely. This gives us a story for exporting pattern synonym definitions that is entirely consistent with existing function definition exports.