假设我有一个像这样的歧视联盟:
type Example =
|Foo of string
|Bar of int
|Baz of int
|Qux of int
|NoValue
是否有任何简洁的方法来完成以下功能而不指定所有剩余的情况
let doIt (ex:Example) =
match ex with
| Foo(_) -> 0
| NoValue -> -1
这样模式将以相同的方式一般地处理剩余的类似结构的并集案例。在示例代码中,它将表示Bar,Baz和Qux的单个case语句,其行为类似于以下内容。
| Bar(i) -> i
我没有在语言参考中看到任何允许这种匹配的内容,但我很好奇是否可能。
答案 0 :(得分:11)
不像你想要的那么简洁,但你可以使用OR pattern做这样的事情:
let doIt (ex:Example) =
match ex with
| Foo(_) -> 0
| NoValue -> -1
| Bar(i) | Baz(i) | Qux(i) -> i;;
然而,它确实消除了该案件的所有(可能)复杂部分的重复。
为了进一步说明,即使您的情况与下列情况完全不符,您也可以这样做:
type Example =
| Foo of string
| Bar of int * int
| Baz of int
| Qux of int
| NoValue
let doIt (ex:Example) =
match ex with
| Foo _ -> 0
| NoValue -> -1
| Bar(i,_) | Baz i | Qux i -> i
答案 1 :(得分:10)
您还可以使用Active Patterns更改受歧视联盟的视图:
let (|SingleInt|_|) = function
| Foo _ -> None
| NoValue -> None
| Bar i | Baz i | Qux i -> Some i
let doIt ex =
match ex with
| SingleInt i -> i
| Foo _ -> 0
| NoValue -> -1
但是如果三个案例应该以相同的方式重复处理,你应该考虑重构你的DUs:
type IntCase = | Bar | Baz | Qux
type Example =
| Foo of string
| SingleInt of int * IntCase
| NoValue
let doIt ex =
match ex with
| SingleInt(i, _) -> i
| Foo _ -> 0
| NoValue -> -1