F# 儿童歧视联盟
如果我有一个有多个值共享一个子项的有区别的联合(F# 儿童歧视联盟,f#,discriminated-union,F#,Discriminated Union,如果我有一个有多个值共享一个子项的有区别的联合(Apple和MoreApples都有typeApple) 是否有方法匹配子联合以消除重复比如: let speakFruit2 = function | _ GrannySmith -> "granny smith" | _ Gala -> "gala" | Banana -> "banana" 这个怎么样 let speakFruit = function | Apple x | MoreApples x ->
Apple
和MoreApples
都有typeApple
)
是否有方法匹配子联合以消除重复比如:
let speakFruit2 = function
| _ GrannySmith -> "granny smith"
| _ Gala -> "gala"
| Banana -> "banana"
这个怎么样
let speakFruit = function
| Apple x | MoreApples x ->
match x with
| GrannySmith -> "Granny Smith"
| Gala -> "gala"
| Banana -> "banana"
我不认为有一种很好的方法可以使用单一模式实现这一点,但您可以定义一个活动模式,它将为您提供两种苹果合并的数据的另一种透视图:
let (|AnyApple|Banana|) = function
| Apple a | MoreApples a -> AnyApple a
| Banana -> Banana
这隐藏了标准的Banana
定义-您可能应该使用另一个名称以避免混淆,但其余名称保持不变。现在,您可以使用AnyApple
进行模式匹配:
let speakFruit = function
| AnyApple GrannySmith -> "granny smith"
| AnyApple Gala -> "gala"
| Banana -> "banana"
部分活动模式也可能是一种解决方案
let (|IsKind|_|) kind z =
match z with
| Apple x | MoreApples x -> if (kind = x) then Some true else None
| _ -> None
let speakFruit x =
match x with
| IsKind GrannySmith z -> "Granny Smith"
| IsKind Gala z -> "Gala"
| Banana -> "banana"
| _ -> "something else"
但老实说,我同意上面的说法。您可能应该重新考虑您的类型。您是完全控制您的类型还是第三方?如果是前者,那么可能会做一些类似的事情?没有办法做到这一点,这实际上是一个迹象,表明您的类型没有充分反映您的域。
let (|IsKind|_|) kind z =
match z with
| Apple x | MoreApples x -> if (kind = x) then Some true else None
| _ -> None
let speakFruit x =
match x with
| IsKind GrannySmith z -> "Granny Smith"
| IsKind Gala z -> "Gala"
| Banana -> "banana"
| _ -> "something else"