Changes between Version 2 and Version 3 of PatternSynonyms


Ignore:
Timestamp:
Jun 12, 2011 10:14:44 AM (4 years ago)
Author:
augustss
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PatternSynonyms

    v2 v3  
    5252Pattern synonyms can be exported and imported by mentioning the ''conid'' in the export/import list.  Note that this suffers from the same constructor vs type confusion that already exists in `hiding` list, i.e., given the mention of a ''conid'' you cannot tell if it refers to a constructor or a type.
    5353
     54You may also give a type signature for a pattern, but as with most other type signatures in Haskell it is optional:
     55
     56`pattern` ''conid'' `::` ''type''
     57
     58E.g.
     59{{{
     60   pattern Arrow :: Type -> Type -> Type
     61   pattern Arrow t1 t2 = App "->" [t1, t2]
     62}}}
     63
    5464== Pattern only synonyms ==
    5565The simple patterns synonyms are restricted to having a right hand side that is also a valid expression.
     
    6878   third (ThirdElem a) = a
    6979   third _ = error "No third"
     80
    7081   fcn :: (Int, (Int, Int))
    7182   fcn (LazySecond x (y, z)) = if x == 0 then 0 else y+z
     
    7586   third (_:_:a:_) = a
    7687   third _ = error "No third"
     88
    7789   fcn :: (Int, (Int, Int))
    78    fcn (x ~(y, z)) = if x == 0 then 0 else y+z
     90   fcn (x, ~(y, z)) = if x == 0 then 0 else y+z
    7991}}}
    8092
     93Together with ViewPatternsAlternative we can now create patterns that look like regular patterns to match on existing (perhaps abstract) types in new ways.
     94{{{
     95   pattern Plus1 n ~ n1 | let n = n1-1, n >= 0
    8196
    82 == Bidirectional synonyms ==
     97   fac 0 = 0
     98   fac (Plus1 n) = (n+1) * fac n
     99}}}
     100Note that the right hand side of `Plus1` binds `n1` and `n`, but since only `n` is mentioned on the left hand side it is the only variable that gets bound when `Plus1` is used.
     101
     102== Bidirectional pattern synonyms ==
     103What if you want to use `Plus1` from the earlier example in an expression.
     104It's clearly impossible since its expansion is a pattern that has no meaning as an expression.
     105Nevertheless, if we want to make what looks like constructors for a type we will often want to use them in both patterns and expressions.
     106This is the rational for the most complicated synonyms, the bidirectional ones.  They provide two expansions, one for patterns and one for expressions.
     107
     108`pattern` ''conid'' ''varid,,1,,'' ... ''varid,,n,,'' `~` ''pat'' `where` ''cfunlhs'' ''rhs''
     109
     110where ''cfunlhs'' is like ''funlhs'', except that the functions symbol is a ''conid'' instead of a ''varid''.
     111
     112Example:
     113{{{
     114   pattern Plus1 n ~ n1 | let n = n1-1, n >= 0 where
     115      Plus1 n = n + 1
     116}}}
     117The first part as is before and describes the expansion of the synonym in patterns, whereas the second describes the expansion in expressions.
     118
     119{{{
     120   fac 0 = 0
     121   fac (Plus1 n) = Plus1 n * fac n
     122}}}