Changes between Version 12 and Version 13 of PatternSynonyms


Ignore:
Timestamp:
Aug 22, 2013 12:57:11 AM (20 months 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.