6

我需要比较两个数字的匹配模式的帮助。像这样的东西:

let test x y =
   match x with
   | y when x < y -> printfn "less than"
   | y when x > y -> printfn "greater than"
   | _ -> printfn "equal"

当 x 为 0 且 y 为 200 时,它以某种方式落入“_”的情况。我在这里做错了什么?

4

6 回答 6

17

您的代码的问题在于,当您编写时:

match x with 
| y when x < y -> (...)

.. 这意味着您要将 (the in ) 的值分配x给一个名为(the <expr>in ) 的新变量,然后将这个新变量(现在包含 的值)与- 的值进行比较,因此这将始终返回。您始终可以重命名绑定变量,因此您的代码与编写相同:match <expr> withy<pat>| <pat> when ...yxxfalse

match x with 
| newY when x < newY -> (...)

现在您可以看到为什么这永远不会匹配 - 因为您只是在x与自己进行比较!

如果您有一些更复杂结构的输入,例如元组或可区分联合、列表、数组、选项类型等,模式匹配特别有用。但是如果您只是想比较数字,则使用起来要容易得多if

let test x y =
  if x < y then printfn "less than"
  elif x > y then printfn "greater than"
  else printfn "equal"

在您的match, 您实际上并不需要绑定任何变量 - 但 John 的解决方案演示了如何使其工作 - 它只是说,获取变量x并将y它们分配给新变量xy(它们只是具有相同的名称)。

于 2013-09-06T03:58:17.807 回答
15

更好的版本是像这样对两个数字进行模式匹配

let test x y =
   match (x,y) with
   | (x,y) when x < y -> printfn "less than"
   | (x,y) when x > y -> printfn "greater than"
   | _ -> printfn "equal"
于 2013-09-06T03:58:22.300 回答
6

如果您向Pattern Matching (F#)咨询您使用哪种类型的模式匹配,那么它将是所谓的变量模式,其中匹配案例中的新变量y将被分配匹配表达式的值x。由于语句y内部的这个变量match隐藏了原始函数参数y,因此在第一种和第二种情况下y将简单地获取 的值x,因此when守卫都失败了。然后,第三个包罗万象的比赛案例_开始,所以你得到“平等”的回报,正如观察到的那样。

如果您浏览以下代码段,您可以更好地了解会发生什么:

let f x y =
    match x with
    | y -> y

并尝试使用类似的东西f arg1 arg2;无论价值如何,f都会返回。arg1arg2

您可以通过将参数比较移动到表达式中来表达您的原始意图,仍然使用与常量模式match匹配:

let test x y =
    match sign (Operators.compare x y) with
    | 1 -> "greater than"
    | -1 -> "less then"
    | _ -> "equal"
于 2013-09-06T04:00:11.103 回答
3

类似于约翰·帕尔默的回答。我认为这样写可以提高你对正在发生的事情的理解:

let test x y = 
    match (x,y) with
    | (a,b) when a < b -> printfn "less than"
    | (a,b) when a > b -> printfn "greater than"
    | _ -> printfn "equal"

简单来说,当您使用Match语句时,模式中的术语(即 之前的部分->)声明了新的标识符。当您y在模式中重复使用时,您将隐藏以前的标识符y并创建一个新的标识符,该标识符与您要匹配的事物具有相同的值,在本例中为标识符x。换句话说,您总是将 的值x与自身进行比较。正如其他人所指出的,这可能最好通过if声明来完成。

于 2013-09-06T18:34:50.450 回答
2

模式匹配是一个糟糕的选择,请if改用:

if x < y then
  printfn "less than"
elif x > y then
  printfn "greater than"
else
  printf "equal"
于 2013-09-06T15:31:06.917 回答
0

替换匹配x匹配y _ _

let test x y =
       match y with
       | y when x < y -> printfn "less than"
       | y when x > y -> printfn "greater than"
       | _ -> printfn "equal"
于 2013-09-06T12:04:18.053 回答