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

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
}
主站蜘蛛池模板: 宣城市| 开封市| 广饶县| 江川县| 贵南县| 基隆市| 贺兰县| 迁安市| 安图县| 阆中市| 无极县| 教育| 宁城县| 玛沁县| 竹北市| 博爱县| 宽城| 沅江市| 綦江县| 凤山市| 邢台市| 大庆市| 连云港市| 金乡县| 嘉定区| 格尔木市| 无为县| 梅州市| 宜君县| 辉南县| 宿松县| 新余市| 临朐县| 札达县| 旺苍县| 恩平市| 新兴县| 浠水县| 彭州市| 黄山市| 翁牛特旗|