如果我有一个有多个价值观的歧视联盟,分享一个孩子(Apple
和MoreApples
都有类型Apple
)......
type Apples =
| GrannySmith
| Gala
type Fruit =
| Apple of Apples
| MoreApples of Apples
| Banana
let speakFruit = function
| Apple GrannySmith
| MoreApples GrannySmith -> "granny smith"
| Apple Gala
| MoreApples Gala -> "gala"
| Banana -> "banana"
有没有办法匹配子联盟以删除重复? - 类似于:
let speakFruit2 = function
| _ GrannySmith -> "granny smith"
| _ Gala -> "gala"
| Banana -> "banana"
答案 0 :(得分:5)
我不认为使用单一模式有一种很好的方法可以做到这一点,但是您可以定义一个活动模式,它将为您提供合并两种苹果的数据的替代视角:
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"
答案 1 :(得分:4)
这个怎么样?
let speakFruit = function
| Apple x | MoreApples x ->
match x with
| GrannySmith -> "Granny Smith"
| Gala -> "gala"
| Banana -> "banana"
答案 2 :(得分:2)
部分活动模式也可以是解决方案
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"
但说实话 - 我同意上面的Fyodor。你可能应该重新考虑你的类型。