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

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
}
主站蜘蛛池模板: 那坡县| 阜新| 蛟河市| 麻江县| 阿鲁科尔沁旗| 宁安市| 会同县| 安多县| 黄大仙区| 松滋市| 东安县| 灵川县| 崇左市| 岑溪市| 鹤山市| 隆子县| 波密县| 新竹县| 宜城市| 婺源县| 利辛县| 兰溪市| 抚松县| 黔东| 富平县| 永德县| 大埔县| 巢湖市| 民丰县| 广宁县| 呼和浩特市| 宽城| 新宁县| 海城市| 金乡县| 呼玛县| 札达县| 原平市| 昭通市| 康平县| 鹤壁市|