元组模式匹配失败

Tuple pattern matching fails

我想匹配一个包含四个项目的元组。

let tupleVar = (1.00, 2.00, 3.00, 4.00)
let verboseMsg (tupleInput: tuple) = 
    match tupleInput with
    | (var1, var2, var3, var4) -> printfn "4 part tuple: %f %f %f %f" var1 var2 var3 var4
    | (var1, var2, var3) -> printfn "3-part tuple: %f %f %f" var1 var2 var3

虽然这个元组不完整,但它已经在第一个匹配行上抛出这个错误:

ParserError: 
Line |
   3 |      | (var1, var2, var3, var4) -> printfn "4 part tuple: %f %f %f %f" …
     |             ~
     | Missing argument in parameter list.

我以为我可以在这个匹配class中创建变量'var1'等。最后我想检查元组中的空值,但它在这里已经失败了。

为什么会出现此错误?

我从微软官方网站的“元组模式”中拿了例子: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching#tuple-pattern

正如 Fyodor 指出的那样,3 元组和 4 元组是两种不同的类型,因此您不能同时匹配两者。我认为您可能想要的是匹配列表类型,因为列表的长度可以是可变的:

let listVar = [1.00; 2.00; 3.00; 4.00]
let verboseMsg listInput = 
    match listInput with
    | [var1; var2; var3; var4] -> printfn "4 part list: %f %f %f %f" var1 var2 var3 var4
    | [var1; var2; var3] -> printfn "3-part list: %f %f %f" var1 var2 var3

verboseMsg listVar   // 4 part list: 1.000000 2.000000 3.000000 4.000000

恰到好处:模式匹配无法做到这一点。除了匹配 variable-length 数据类型之外,您还可以做的是 object-orientated 方法重载,但还有一个额外的变化。考虑:

type Foo = Foo with
    static member T (var1, var2, var3, var4) = printfn "4 part tuple: %f %f %f %f" var1 var2 var3 var4
    static member T (var1, var2, var3) = printfn "3-part tuple: %f %f %f" var1 var2 var3

Foo.T (1., 2., 3., 4.)
Foo.T (1., 2., 3.)

行得通。绑定到变量的元组怎么样?

let t4 = 1., 2., 3., 4.
let t3 = 1., 2., 3.

作为参数传递,它们可以被视为 (float * float * float * float)(float * float * float) 类型,与它们声称的 float * float * float * floatfloat * float * float 类型完全不同拥有。

type Foo with
    static member T ((var1, var2, var3, var4)) = Foo.T (var1, var2, var3, var4)
    static member T ((var1, var2, var3)) = Foo.T (var1, var2, var3)

Foo.T t4
Foo.T t3