了解与cons运算符的模式匹配

时间:2010-05-17 04:01:37

标签: f# pattern-matching cons

在“编程F#”中,我遇到了像这样的模式匹配(我简化了一点):

let rec len list = 
  match list with
  | [] -> 0
  | [_] -> 1
  | head :: tail -> 1 + len tail;;

实际上,我知道最后一个匹配会识别列表的头部和尾部。从概念上讲,我不明白为什么它有效。据我所知,::是cons运算符,它在列表的头部位置附加一个值,但它并不像我在这里被用作运算符。我应该将其理解为列表的“特殊语法”,其中::根据上下文被解释为运算符或“匹配模式”吗?或者可以使用其他运算符为列表以外的类型扩展相同的想法吗?

3 个答案:

答案 0 :(得分:13)

这是列表的特殊语法。你可以将list类型视为一个有区别的联盟:

type list<'T> =         // '
    | Nil
    | Cons of 'T * list<'T>

除了有特殊语法使Nil[]Cons(h,t)h::t。然后它就是一个有区别的联合的正常模式匹配。这有帮助吗?

(可能还会看到this blog entry。)

答案 1 :(得分:10)

除了Brian的回答,还有一些值得注意的地方。 h::t语法可以用作运算符作为模式:

let l = 1::2::[]                    // As an operator
match l with x::xs -> 1 | [] -> 0   // As a pattern

这意味着它是一个有点特殊的构造,因为其他运算符(例如+)不能用作模式(用于将结果分解回运算符的参数) - 显然,对于{{1这将是模棱两可的。

此外,模式+很有趣,因为它是嵌套模式的一个示例。它组成:

  • [_] - 下划线模式,匹配任何值且不绑定任何符号
  • _ - 单元素列表模式,它匹配具有单个元素的列表,并将列表元素与嵌套[ <pattern> ]匹配。

您还可以编写<pattern>,它将返回单个元素的值(在本例中为1)。

答案 2 :(得分:2)

它用作格式化程序或正式pattern,“list”与三种模式匹配:

[]表示列表为空

[_]表示列表中有一个元素,因为你不关心元素是什么,所以只需将_放在那里,你也可以使用[a]。

head :: tail意味着列表有两个部分:头部和尾部。

您可以将F#模式匹配视为强大的if then else结构。