官术网_书友最值得收藏!

Pattern matching

Pattern matching is a generalization of C language or Java's switch statement. In C language and Java, the switch statement only allows you to choose from many statements based on an integer (including char) or an enum value. While in Opa, pattern matching is more powerful than that. The more general syntax for pattern matching is:

match(<expr>){
case <case_1>: <expression_1>
case <case_2>: <expression_2>
case <case_n>: < expression_n>
}

When a pattern is executed, <expr> is evaluated to a value, which is then matched against each pattern in order until a case is found. You can think about it this way:

if (case_1 matched) expression_1 else {
  if (case_2 matched) expression_2 else {
    ...
         if (case_n matched) expression_n else no_matches
         ...
  }
}

The rules of pattern matching are simple and are as follows:

  • Rule 1: Any value matches the pattern _
  • Rule 2: Any value matches the variable pattern x, and the value is bound to the identifier x
  • Rule 3: An integer/float/string matches an integer/float/string pattern when they are equal
  • Rule 4: A record (including tuples and lists) matches a closed record pattern when both records have the same fields and the value of the fields matches the pattern component-wise
  • Rule 5: A record (including tuples and lists) matches an open record pattern when the value has all the fields of the pattern (but can have more) and the value of the common fields matches the pattern component-wise
  • Rule 6: A value matches a pattern as x pattern when the value matches the pattern, and additionally it binds x to the value
  • Rule 7: A value matches an OR pattern if one of the values matches one of the two subpatterns
  • Rule 8: In all the other cases, the matching fails

The first three and the last three rules (rule 1, 2, 3, 6, 7, 8) are easy to understand. Let's take a look at them:

match(y){
case 0:       //if y == 0, match [rule 3]
case 1 as x:  //if y == 1, match and 1 is bound to x [rule 6]
case 2 | 3 :  //if y is 2 or 3, match [rule 7]
case x:       //any value will match and the value is bound
                //to x [rule 2]
case _:       //match, we do not care about the value.
}
Note

This code will not compile, we just used it to illustrate the rules.

Rule 4 and rule 5 are a little more complicated. A close record pattern is a record with fixed fields. An open record pattern is a record that ends with to indicate that it may have other fields we do not care about. The following examples may make that clearer:

x = {a:1, b:2, c:3}
match(x){
case {a:1,b:2}:     //a close record pattern, but will not match //cause they do not have the same fields [rule 4]
case {a:1,b:2,c:2}: //a close record pattern, still will not match //cause c is not equal [rule 4]
case {a:1,b:2,...}: //An open record pattern, matches [rule 5]
}

We can also match tuples and lists (since tuples and lists are special records, they are not hard to understand). For example:

t = (1,"2",3.0)
match(t){         //matching a tuple
case (1,"2",3.1): //not match, 3.1 != 3.0
case (1,"2",_):   //match, _ matches anything
case (1,"2",x):   //match, now x = 3.0
case {f1:1 ...}:  //match, remember tuples are just records
}
y = [1,2,3]
match(y){         //matching a list
case [1,2]:       //not match
case [1,2,_]:     //match, _ matches anything
case [1,2,x]:     //match, now x = 3
case [2,|_]:      //not match, '|_' means the rest of the list
case [1,|_]:      //match 
case [1,2,|_]:    //match
case [1,x|_]:     //match, now x = 2
}
主站蜘蛛池模板: 大城县| 南充市| 三穗县| 井研县| 德庆县| 无锡市| 景谷| 巫溪县| 彩票| 赣州市| 海伦市| 修文县| 神农架林区| 武汉市| 临安市| 瓮安县| 徐汇区| 安陆市| 庆安县| 呈贡县| 武乡县| 冕宁县| 原阳县| 达孜县| 库车县| 临城县| 大港区| 彰化县| 固阳县| 溧阳市| 兴城市| 乌海市| 玉溪市| 湖口县| 抚州市| 徐州市| 东乡| 泾川县| 苏州市| 铅山县| 宁武县|