F# 是否有可能在一个受歧视的联合体的基本形状上进行模式匹配?

F# 是否有可能在一个受歧视的联合体的基本形状上进行模式匹配?,f#,functional-programming,pattern-matching,discriminated-union,active-pattern,F#,Functional Programming,Pattern Matching,Discriminated Union,Active Pattern,F#是否支持通过标准以外的标准对受歧视的联合成员实例进行模式匹配 例如,假设我想匹配数据的基本形状,我想考虑任何一个具有 int *int /代码>形状的东西,而不考虑DU如何对值进行分类。是 下面是我现在的做法: type ExampleDU = | BinaryCase1 of x:int * y:int | BinaryCase2 of x:int * y:int | UnaryCase1 of x:int let underlyingValue = (1,2) let

F#是否支持通过标准以外的标准对受歧视的联合成员实例进行模式匹配

例如,假设我想匹配数据的基本形状,我想考虑任何一个具有<代码> int *int /代码>形状的东西,而不考虑DU如何对值进行分类。是

下面是我现在的做法:

type ExampleDU = 
  | BinaryCase1 of x:int * y:int
  | BinaryCase2 of x:int * y:int
  | UnaryCase1  of x:int

let underlyingValue = (1,2)
let asCase1 = BinaryCase1 underlyingValue
let asCase2 = BinaryCase2 underlyingValue

let shapeName = 
  match asCase1 with
  | BinaryCase1 (x,y) | BinaryCase2 (x,y) -> "pair" // is this possible without explicitly writing the name for each part?
  | _ -> "atom"
我想要更接近以下内容的内容:

let shapeName = 
  match asCase1 with
  | (x,y) -> "pair" 
  | _ -> "atom"
在F#中是否有一些类似的表达语法目前得到了支持,或者我是否必须明确指定所有情况


注意:我知道我可以通过反射找到我想要的信息,但我对这样的解决方案不感兴趣。

这里是活动模式的答案

let (|Pair|_|) input = 
    match input with
    |BinaryCase1(a,b)
    |BinaryCase2(a,b) -> Some(a,b)
    | _ -> None
以及用法

match asCase1 with |Pair(a,b) -> printfn "matched" | _ -> ();;

您可以为此使用活动模式,但不能将其老化easily@JohnPalmer您是否有任何关于将活动模式与歧视联合使用的参考资料?我可能会从一个示例用法中找出如何做我想做的事情为什么要这样做?两个案例的形状相似这一事实应该是完全偶然的。DU的全部要点是。。。好区分相互排斥的情况。根据定义,两种不同的情况没有任何共同之处,即使有时看起来它们具有相同的形状。@MarkSeemann DU的成员是相互排斥的。这意味着不存在多个DU成员实例的对象。然而,“两个不同的案例没有任何共同之处”太过强烈了。您似乎认为不相交联合的定义要求不同成员的实例不能共享公共属性。不过我很确定这是错误的。实际上,DU的不同成员的实例很可能共享属性,因为同样的原因,它们被声明在同一个范围内。@MarkSeemann我在不同的DU成员中识别一个公共形状的目的是经济地处理它们实例的共享属性。我明白了-但是看起来这种方法仍然需要枚举每个情况并分配形状的代码(每个有区别的联合的活动模式)。或者,你是说这可以被推广到跨不同的DU类型的更可重用的东西吗?这根本不能被推广。