代码之家  ›  专栏  ›  技术社区  ›  Mathias

使用cons运算符了解模式匹配

  •  11
  • Mathias  · 技术社区  · 14 年前

    在“编程F”中,我遇到了一个类似于此的模式匹配(我简化了一点):

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

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

    3 回复  |  直到 14 年前
        1
  •  10
  •   Tomas Petricek    14 年前

    除了布莱恩的回答之外,还有几点值得注意。这个 h::t 语法可以同时用作运算符 作为一种模式:

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

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

    另外,模式 [_] 很有趣,因为它是嵌套模式的一个例子。它构成:

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

    你也可以写 match 1::[] with | [x] -> x 它将返回单个元素的值(在本例中是1)。

        2
  •  13
  •   Brian    14 年前

    它是列表的特殊语法。你可以想到 list 作为歧视工会类型:

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

    除了有特殊的语法 Nil [] Cons(h,t) h::t . 那么它只是一个有区别的联合体上的正常模式匹配。这有帮助吗?

    (也可能参见 this blog entry )

        3
  •  2
  •   Yin Zhu    14 年前

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

    []表示列表为空

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

    head::tail表示列表有两部分:head和tail。

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