我需要比较两个数字的匹配模式的帮助。像这样的东西:
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 时,它以某种方式落入“_”的情况。我在这里做错了什么?
我需要比较两个数字的匹配模式的帮助。像这样的东西:
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 时,它以某种方式落入“_”的情况。我在这里做错了什么?
您的代码的问题在于,当您编写时:
match x with
| y when x < y -> (...)
.. 这意味着您要将 (the in ) 的值分配x
给一个名为(the <expr>
in ) 的新变量,然后将这个新变量(现在包含 的值)与- 的值进行比较,因此这将始终返回。您始终可以重命名绑定变量,因此您的代码与编写相同:match <expr> with
y
<pat>
| <pat> when ...
y
x
x
false
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
它们分配给新变量x
和y
(它们只是具有相同的名称)。
更好的版本是像这样对两个数字进行模式匹配
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"
如果您向Pattern Matching (F#)咨询您使用哪种类型的模式匹配,那么它将是所谓的变量模式,其中匹配案例中的新变量y
将被分配匹配表达式的值x
。由于语句y
内部的这个变量match
隐藏了原始函数参数y
,因此在第一种和第二种情况下y
将简单地获取 的值x
,因此when
守卫都失败了。然后,第三个包罗万象的比赛案例_
开始,所以你得到“平等”的回报,正如观察到的那样。
如果您浏览以下代码段,您可以更好地了解会发生什么:
let f x y =
match x with
| y -> y
并尝试使用类似的东西f arg1 arg2
;无论价值如何,f
都会返回。arg1
arg2
您可以通过将参数比较移动到表达式中来表达您的原始意图,仍然使用与常量模式match
匹配:
let test x y =
match sign (Operators.compare x y) with
| 1 -> "greater than"
| -1 -> "less then"
| _ -> "equal"
类似于约翰·帕尔默的回答。我认为这样写可以提高你对正在发生的事情的理解:
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
声明来完成。
模式匹配是一个糟糕的选择,请if
改用:
if x < y then
printfn "less than"
elif x > y then
printfn "greater than"
else
printf "equal"
替换匹配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"