如何使用模式匹配检测Ocaml中的交换模式?

Cal*_*lin 7 warnings ocaml pattern-matching

我需要在我的一个函数中检测到一个可交换模式.我认为编写以下内容将完成工作:

let my_fun a b = match a,b with
  (*...*)
  | a,b
  | b,a when is_valid b -> process b  (***)
  (*...*)
Run Code Online (Sandbox Code Playgroud)

这不起作用,Ocaml抱怨这个子模式是 标记为的行的未使用警告(***).

1)有人可以向我解释这个警告试图说什么以及为什么这不起作用?

2)如果不if then else考虑我现在想要哪个参数的事实,我怎样才能真正优雅地写出这个is_valid

2)是否可以仅使用模式匹配来获得预期的功能而不重复,when is_valid b -> process b因为它发生在下面?

let my_fun a b = match a,b with
  (*...*)
  | a,b when is_valid b -> process b
  | b,a when is_valid b -> process b 
  (*...*)
Run Code Online (Sandbox Code Playgroud)

编辑:

在我的具体例子中a,b是成对的.该功能有点复杂,但以下将说明这种情况:

let f a b = match a,b with
  | (a1,a2),(b1,b2)
  | (b1,b2),(a1,a2) when b1 = b2 -> a1 + a2
Run Code Online (Sandbox Code Playgroud)

调用f (1,1) (1,2)将导致模式匹配失败.我知道理解为什么(感谢下面的答案),如果我对每个元素都有不同的构造函数,我理解如何使它工作(如在Ashish Agarwal的答案中).你能建议一种方法让它适用于我的情况吗?

nlu*_*oni 7

匹配首先匹配模式,如果成功,则通过从该模式匹配的附加环境评估条件.由于a,b将始终绑定,这是唯一使用的情况,并且编译器正确报告b,a从未使用过的情况.你必须重复这一行,

let my_fun a b = match a,b with
  | a,b when is_valid b -> process b
  | b,a when is_valid b -> process b
Run Code Online (Sandbox Code Playgroud)

如果您没有对变量执行匹配,但是对某些变量执行匹配,则您的方法可以正常工作,例如,

let my_fun a b = match a,b with
  | a, `Int b
  | `Int b, a when is_valid b -> process b
Run Code Online (Sandbox Code Playgroud)

编辑:使用一个保护作为子表达来考虑多个模式,

let my_fun a b = match a,b with
  | ((a,b) | (b,a)) when is_valid b -> process b
Run Code Online (Sandbox Code Playgroud)

你会在模式的定义中看到这个例子.它实际上是一种模式,由模式组成,匹配.