利弊模式中的带括号的模式

时间:2017-05-21 04:32:27

标签: .net f# pattern-matching

Pattern Matching的Microsoft指南中,有一个括号模式的示例:

  

可以围绕模式对括号进行分组,以实现所需的关联性。在以下示例中,括号用于控制AND模式和cons模式之间的关联。

let countValues list value =
    let rec checkList list acc =
       match list with
       | (elem1 & head) :: tail when elem1 = value -> checkList tail (acc + 1)
       | head :: tail -> checkList tail acc
       | [] -> acc
    checkList list 0

countValues [ for x in -10..10 -> x*x - 4 ] 0

(elem1 & head) :: tail when elem1 = value模式如何运作?这与:

相同
| head :: tail when elem1 = value

2 个答案:

答案 0 :(得分:3)

我必须承认,我没有看到这个特定例子的用处。

您的案例中的分组只是意味着它将相同的值与两个不同的变量匹配,headelem1都包含列表的头部。

此匹配的更简单示例是

let (a & b) = x
x = a // true
x = b // true
a = b // true

let (head & elem1) :: tail = [1;2;3;4]
head = 1 // true
elem1 = 1 // true
tail = [2;3;4] // true

所以给出你的例子,模式简单地等于

| head :: tail when head = value

旁注,您可以将括号放在任何和所有模式上。

答案 1 :(得分:3)

文档中的示例是说明特定段落的一个非常糟糕的选择 - 它使用了深奥而臭名昭着的无用&模式,似乎将整个注意力吸引到自身,并减损了段落的含义

要点是这之间存在差异:

...
match list with
| elem1 & head :: tl -> ...
...

和此:

...
match list with
| (elem1 & head) :: tl -> ...
...

其中在第一个示例中elem1绑定到整个列表,而在第二个示例中,它仅绑定到列表的第一个元素(正如其名称所示),因为parens强制执行操作顺序。

更简单的说明就是展示a::b::tl(a::b)::tl如何反映不同类型(分别为'a list'a list list)。