为什么在F#中管道和何时需要虚拟符号文字?

Ber*_*dei 3 f# design-patterns symbols matching

我是F#的新手并且正在摆弄它.得到的是我:

let rec fact n =
  match n with 
    | dummy when n < 2 -> 1
    | _ -> n * fact (n - 1)

let x = 6
printfn "%d! = %d" x (fact x)
Run Code Online (Sandbox Code Playgroud)

为什么F#需要在管道之间和何时使用这个虚拟占位符?Dummy甚至整个时间都是未定义的,编译器似乎在某种程度上需要并同时忽略它,就像需要的鬼符号一样.

提前致谢.

kvb*_*kvb 10

符号不必是虚拟符号,可以出现在when子句中.例如,您的函数可以重写:

let rec fact = function
| n when n < 2 -> 1 
| n -> n * fact (n - 1) 
Run Code Online (Sandbox Code Playgroud)

在这里,因为我们使用的是匿名模式匹配function而不是match ... with,所以标识符实际上很重要.

通常你会使用更复杂的模式,比如

match p with
| i,j when i < j -> true
| _ -> false
Run Code Online (Sandbox Code Playgroud)

因为即使存在when子句,匹配的模式几乎总是很重要,所以没有一种允许when没有任何模式的子句的特殊形式.

当然,如果你真的希望它是一个虚拟的,你可以使用这个模式,_这样你就不需要提出一个新的标识符名称:

let rec fact n = 
  match n with  
  | _ when n < 2 -> 1 
  | _ -> n * fact (n - 1) 
Run Code Online (Sandbox Code Playgroud)

  • @gradbot:嗯,我觉得这对初学者来说是一个非常先进的功能! (3认同)

Tom*_*cek 9

正如其他人已经解释的那样,dummy您的示例中的值可以替换为忽略模式(写为_)以使代码更简洁.match当您需要分解某个值时,该构造是最强大的,在这种情况下,您需要能够在模式匹配中定义新符号.

但是,在您的示例中,您并没有真正分解该值,因此我更喜欢简单的if ... then表达式而不是更复杂的match:

let rec fact n = 
  if n < 2 then 1 
  else n * fact (n - 1) 
Run Code Online (Sandbox Code Playgroud)

我认为这是一种更易读的原始函数编写方式(与其他版本一样功能 - match在处理比整数更复杂的类型时更合适).