如何比较F#中的x和y?

Tri*_*Gao 5 f# pattern-matching

我需要帮助匹配2个数字的匹配模式.像这样的东西:

let test x y =
   match x with
   | y when x < y -> printfn "less than"
   | y when x > y -> printfn "greater than"
   | _ -> printfn "equal"
Run Code Online (Sandbox Code Playgroud)

不知何故,当x为0且y为200时,它落入"_"情况.我在这里做错了什么?

Tom*_*cek 15

您的代码的问题是,当您写:

match x with 
| y when x < y -> (...)
Run Code Online (Sandbox Code Playgroud)

..这意味着你要的值分配x(在<expr>match <expr> with)来命名一个新的变量y(在<pat>| <pat> when ...),然后比较这新的y(现在包含的值x)与价值x-因此这将始终返回false.您始终可以重命名绑定变量,因此您的代码与编写相同:

match x with 
| newY when x < newY -> (...)
Run Code Online (Sandbox Code Playgroud)

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

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

let test x y =
  if x < y then printfn "less than"
  elif x > y then printfn "greater than"
  else printfn "equal"
Run Code Online (Sandbox Code Playgroud)

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


Joh*_*mer 14

一个更好的版本是两个数字上的模式匹配,如此

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"
Run Code Online (Sandbox Code Playgroud)


Gen*_*ski 5

如果您使用模式匹配(F#)查询您使用的模式匹配类型,那么它将是所谓的变量模式,其中y匹配情况中的新变量将被赋予匹配表达式的值x.由于此y变量内部match语句会影响原始函数参数y,因此在第一种情况和第二种情况下y只会获得值x,因此when防护都会失败.然后,第三个全能比赛案例_开始,所以你得到"平等"的回报,如所观察到的那样.

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

let f x y =
    match x with
    | y -> y
Run Code Online (Sandbox Code Playgroud)

并尝试类似的东西f arg1 arg2; 无论价值如何,f都会一直回来.arg1arg2

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

let test x y =
    match sign (Operators.compare x y) with
    | 1 -> "greater than"
    | -1 -> "less then"
    | _ -> "equal"
Run Code Online (Sandbox Code Playgroud)