Changes between Initial Version and Version 1 of PatternSynonyms/Implementation

Oct 19, 2013 1:05:50 PM (6 years ago)



  • PatternSynonyms/Implementation

    v1 v1  
     1= Frontend representation
     3After parsing, and during renaming, pattern synonyms are stored as
     6= Typechecking
     8The typechecking pass turns `PatSynDecl`s into a `PatSyn` and several
     9`HsBind`s. To fill in the `PatSyn`, we typecheck the right-hand side
     10of the pattern synonym declaration, then do some extra processing on
     11it to reject as-patterns and optionally compute the reverse of the
     12pattern synonym (for implicitly bidirectional ones). Afterwards, we
     13collect universal & existential type variables and typeclass dictionary
     14variables to be used when creating `ConPatOut` patterns from pattern
     15synonym occurances, and generate some `HsBind`s:
     17* The `PatSyn` stores typing information for the pattern synonym, to
     18  be consulted when typechecking pattern synonym usage sites.
     20* The first `HsBind` is the binder for the matcher function generated from
     21  the pattern synonym. The matcher is used when desugaring pattern
     22  synonym usage sites (see below).
     24* For bidirectional pattern synonyms, another `HsBind` called a
     25  wrapper is created to be used for pattern synonym usages in
     26  expression contexts. It is a wrapper in the same sense as a
     27  constructor wrapper.
     29Pattern synonym occurances in patterns are turned into `ConPatOut`s
     30just like regular constructor matches. `ConPatOut` has been changed to
     31store a `ConLike` instead of a `DataCon`; the `ConLike` type is simply
     32the sum of `DataCon` and `PatSyn`.
     36= Desugaring
     38`ConLike`s are handled uniformly all the way until
     39`mkCoAlgCaseMatchResult`. There, we have a mixed list of `DataCon` and
     40`PatSyn`-based patterns.
     43=== Grouping
     45This list is grouped so that subsequent `DataCon` patterns are put in
     46the same group, and `PatSyn` patterns are all in their own
     47groups. This is needed so that when doing pattern matching per column,
     48given e.g.
     52data T = MkT1 | MkT2 Bool | MkT3
     53pattern P x = MkT2 x
     56and a list of cases
     60MkT1 _ -> alt1
     61P True -> alt2
     62MkT2 _ -> alt3
     65we don't compile that into
     69DEFAULT -> ... P ...
     70MkT1 -> alt1
     71MkT2 _ -> alt3
     74since we can't see into P (and we don't want to, since it might be
     75imported from another module). The correct thing to do is to compile
     76that into
     80DEFAULT -> ... (P, alt2) and (MkT2 _, alt3) ...
     81MkT1 -> alt1
     84Consecutive occurances of the same pattern synonym (e.g. if we had `P
     85True` and `P False` in the previous example) are compiled into a
     86single match; the arguments are then matched in a sub-case.
     89== Matching
     91For each pattern synonym, a matcher function is generated which gets a
     92scrutinee and a success and a failure continuations. Given a type
     95data T a where
     96     MkT :: (Cls b) => b -> a -> T a
     99and a pattern synonym
     103pattern P x y = MkT x y
     106we generate the matcher function
     110P :: forall r a. T a -> (forall b. Cls b => b -> a -> r) -> r -> r
     111P scrutinee pass fail = case scrutinee of
     112  MkT x y -> pass x y
     113  _ -> fail
     116Occurances of pattern synonyms are then desugared into calls to this
     117matcher function. This allows pattern synonym definitions to be just
     118as opaque as function definitions: their type defines their interface
     119completely. This gives us a story for exporting pattern synonym
     120definitions that is entirely consistent with existing function
     121definition exports.