我是 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)
为什么 F# 在管道和何时需要这个虚拟占位符?Dummy 甚至一直是未定义的,编译器似乎以某种方式需要并同时忽略它,就像需要的幽灵符号一样。
提前致谢。
我是 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)
为什么 F# 在管道和何时需要这个虚拟占位符?Dummy 甚至一直是未定义的,编译器似乎以某种方式需要并同时忽略它,就像需要的幽灵符号一样。
提前致谢。
该符号不必是虚拟符号,可以出现在 when 子句中。例如,您的函数可以重写:
let rec fact = function
| n when n < 2 -> 1
| n -> n * fact (n - 1)
在这里,因为我们使用的是匿名模式匹配function
而不是match ... with
,所以标识符实际上很重要。
通常你会使用更复杂的模式,比如
match p with
| i,j when i < j -> true
| _ -> false
因为即使有when
子句,匹配的模式几乎总是很重要,所以没有一种特殊的形式允许when
没有任何模式的子句。
当然,如果你真的希望它是一个虚拟的,你可以使用这个模式_
,这样你就不需要想出一个新的标识符名称:
let rec fact n =
match n with
| _ when n < 2 -> 1
| _ -> n * fact (n - 1)
正如其他人已经解释的那样,dummy
您的示例中的值可以替换为忽略模式(写为_
),以使代码更简洁。match
当您需要分解某些值时,该构造是最强大的,在这种情况下,您需要能够在模式匹配中定义新符号。
但是,在您的示例中,您并没有真正分解值,所以我更喜欢简单if ... then
的表达式而不是更复杂的match
:
let rec fact n =
if n < 2 then 1
else n * fact (n - 1)
我认为这是编写原始函数的一种更易读的方式(并且与其他版本一样实用——match
在处理比整数更复杂的类型时更适合)。
dummy
仅表示可以匹配 和 之间的值的值(或更准确地说是模式match
)with
。它在您的函数之外不可见,仅在第一种情况下可见。
正如 kvb 所说,您不必为它命名dummy
,它可以是任何有效的 F# 标识符。
它非常强大,因为它可以用于分解元组或列表等类型:
match l with
| head::tail -> tail // returns tail
| _ -> [] // returns an empty list