Changes between Version 12 and Version 13 of PatternSynonyms


Ignore:
Timestamp:
Aug 22, 2013 12:57:11 AM (2 years ago)
Author:
cactus
Comment:

Updated to reflect details of current work-in-progress implementation

Legend:

Unmodified
Added
Removed
Modified
  • PatternSynonyms

    v12 v13  
    3535}}}
    3636
    37 Furthermore, pattern synonyms can also be used in expressions, e.g.,
    38 {{{
    39    arrows :: [Type] -> Type -> Type
    40    arrows = flip $ foldr Arrow
    41 }}}
     37== Pattern-only synonyms ==
    4238
    43 == Simple pattern synonyms ==
    4439The simplest form of pattern synonyms is the one from the examples above.  The grammar rule is:
    4540
    46 `pattern` ''conid'' ''varid,,1,,'' ... ''varid,,n,,'' `=` ''patexp''
     41`pattern` ''conid'' ''varid,,1,,'' ... ''varid,,n,,'' `=` ''pat''
    4742
    48 where ''patexp'' is the intersection of the grammars for patterns and expression, i.e., those terms that are valid both as a pattern and as an expression.
    49  * Each of the variables on the left hand side must occur exactly once on the right hand side, and these are the only variables that can occur on the right hand side. 
     43`pattern` ''varid,,1,,'' ''consym'' ''varid,,2,,'' `=` ''pat''
     44
     45 * Each of the variables on the left hand side must occur exactly once on the right hand side
    5046 * Pattern synonyms are not allowed to be recursive.  Cf. type synonyms.
    5147 * The semantics is simply expansion of the synonym.
    5248
    53 Pattern 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 a `hiding` list, i.e., given the mention of a ''conid'' you cannot tell if it refers to a constructor or a type.
     49Pattern synonyms can be exported and imported by prefixing the ''conid'' with the keyword `pattern`:
     50
     51{{{
     52   module Foo (pattern Arrow) where ...
     53}}}
     54
     55This is required because pattern synonyms are in the namespace of constructors, so it's perfectly valid to have
     56
     57{{{
     58   data P = C
     59   pattern P = 42
     60}}}
    5461
    5562You may also give a type signature for a pattern, but as with most other type signatures in Haskell it is optional:
     
    6370}}}
    6471
    65 == Pattern only synonyms ==
    66 Simple patterns synonyms are restricted to having a right hand side that is also a valid expression.
    67 Pattern only synonyms can have any pattern on the right hand side, but may only be used in patterns.
    68 
    69 `pattern` ''conid'' ''varid,,1,,'' ... ''varid,,n,,'' `=` ''pat''
    70 
    71 Again, each of the variables on the left hand side must be mentioned exactly once on the right hand side, but now the right hand side can mention other variables as well.  These variables will not be bound when using the pattern synonym.
    72 
    73 Examples:
    74 {{{
    75    pattern ThirdElem x = _:_:x:_
    76    pattern LazySecond a b = (a, ~b)
    77 
    78    third (ThirdElem a) = a
    79    third _ = error "No third"
    80 
    81    fcn :: (Int, (Int, Int))
    82    fcn (LazySecond x (y, z)) = if x == 0 then 0 else y+z
    83 }}}
    84 And their expansions
    85 {{{
    86    third (_:_:a:_) = a
    87    third _ = error "No third"
    88 
    89    fcn :: (Int, (Int, Int))
    90    fcn (x, ~(y, z)) = if x == 0 then 0 else y+z
    91 }}}
    92 
    9372Together with ViewPatternsAlternative we can now create patterns that look like regular patterns to match on existing (perhaps abstract) types in new ways.
    9473{{{
     
    9877   fac (Plus1 n) = (n+1) * fac n
    9978}}}
     79
     80
    10081Note 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.
    10182
    102 == Bidirectional pattern synonyms ==
     83Another example showing pattern synonyms used as views, with regular ViewPatterns:
     84
     85{{{
     86import qualified Data.Sequence as Seq
     87
     88pattern Empty = (Seq.viewl -> Seq.EmptyL)
     89pattern x :< xs = (Seq.viewl -> x Seq.:< xs)
     90pattern xs :> x = (Seq.viewr -> xs Seq.:> x)
     91}}}
     92
     93
     94
     95== Implicitly-bidirectional pattern synonyms ==
     96
     97In cases where ''pat'' is in the intersection of the grammars for patterns and expressions (i.e. is valid both as an expression and a pattern), the pattern synonym is said to be bidirectional, and can be used in expression contexts as well.
     98
     99For example, the following two are not bidirectional:
     100
     101{{{
     102   pattern ThirdElem x = _:_:x:_
     103   pattern Snd y = (x, y)
     104}}}
     105
     106since the right-hand side is not a closed expression of {''x''} and {''y''} respectively.
     107
     108In contrast, the pattern synonyms for ''Arrow'' and ''Int'' above are bidirectional, so you can e.g. write:
     109
     110{{{
     111   arrows :: [Type] -> Type -> Type
     112   arrows = flip $ foldr Arrow
     113}}}
     114
     115
     116== Explicitly-bidirectional pattern synonyms ==
     117
    103118What if you want to use `Plus1` from the earlier example in an expression?
    104119It's clearly impossible since its expansion is a pattern that has no meaning as an expression.