模式匹配和构造函数

cod*_*nk1 1 ocaml functional-programming pattern-matching

为什么我在编写这种模式匹配时会出错:

type t = A of int | B of float

let f = function
        | (A i | B f) -> true
        | _ -> false
Run Code Online (Sandbox Code Playgroud)

要么

let f = function
        | A i | B f -> true
        | _ -> false
Run Code Online (Sandbox Code Playgroud)

错误:变量f必须出现在此|的两侧 图案

let f = function
        | (A i | B i) -> true
        | _ -> false
Run Code Online (Sandbox Code Playgroud)

要么

let f = function
        | A i | B i -> true
        | _ -> false
Run Code Online (Sandbox Code Playgroud)

错误:此模式匹配float类型的int类型的值, 但预期模式匹配value

Ste*_*ans 8

如果为多个模式提供单个右侧(就像您一样),OCaml要求模式始终与模式变量绑定.

在第一种情况下,

match ... with
  | A i | B f -> ...
  ...
Run Code Online (Sandbox Code Playgroud)

模式与它们绑定的变量不一致:第一个模式绑定i,而第二个模式绑定f.

在第二种情况下,

match ... with
  | A i | B i -> ...
  ...
Run Code Online (Sandbox Code Playgroud)

模式与要绑定到变量的值的类型不一致:第一个模式将type的值绑定inti,而第二个模式将type的值绑定floati.

这两个模式可以一致地绑定到变量的唯一方法是不要绑定到任何变量:

match ... with
  | A _ | B _ -> ...
  ...
Run Code Online (Sandbox Code Playgroud)

完整的例子就变成了

type t = A of int | B of float

let f = function
  | A _ | B _ -> true
  | _ -> false
Run Code Online (Sandbox Code Playgroud)

(但请注意,模式匹配的最后一臂是多余的,因为前两个模式已经穷尽地匹配了您的类型的所有值t.因此,我们得到:

let f = function
  | A _ | B _ -> true
Run Code Online (Sandbox Code Playgroud)

这当然等同于写作let f _ = true.)