如何解构构造函数参数?

How to destructure a constructor argument?

在 F# 中,我可以在语法中的多个位置使用模式匹配。

例如:

// Given this type...
type SingleCaseUnion = | SingleCaseUnion of int

/// ...I can do this:
let destructureInFunc (SingleCaseUnion n) =
    printfn "%d" n

// ...and this:
type DestructureInMethod() =
    member t.M(SingleCaseUnion n) =
        printfn "%d" n

但我不知道该怎么做:

type DestructureInCtor(SingleCaseUnion n) =
    do printfn "%d" n

//  type DestructureInCtor(SingleCaseUnion n) =
//  ---------------------------------------^
//
// stdin(3,40): error FS0010: Unexpected identifier in type definition. Expected ')' or other token.

是我的语法有误,还是 F# 不支持构造函数参数中的模式匹配?

不,language spec 明确表示不:

primary-constr-args : attributesopt accessopt (simple-pat, ... , simplepat)
simple-pat :
 | ident
 | simple-pat : type

正如已经指出的那样,辅助构造函数允许模式匹配参数,但与主构造函数的不同之处在于每个主构造函数都是函数参数私有字段声明。

如果 F# 在这里允许模式匹配,就会有一些模式会破坏这种单参数单字段关系。

type DestructureInCtor(SingleCaseUnion _) = 
    // doesn't declare a private field

或:

type DestructureInCtor((a:int, b:int)) = 
    // declares two private fields? 

这并非不可想象,但我猜测允许扩展模式匹配以提供字段声明的复杂性超过了好处。