Reputation: 157
Lets say I have a discriminated union like this:
type Example =
|Foo of string
|Bar of int
|Baz of int
|Qux of int
|NoValue
Is there any concise way to complete the following function without specifying all the remaining cases
let doIt (ex:Example) =
match ex with
| Foo(_) -> 0
| NoValue -> -1
Such that the pattern will generically handle the remaining similarly structured union cases the same way. In the example code, it would mean a single case statement for Bar,Baz, and Qux that would behave like the following.
| Bar(i) -> i
I didn't see anything in the language reference that would allow this type of matching but I'm curious if it's possible.
Upvotes: 5
Views: 1554
Reputation: 19897
Not quite as concise as you want, but you can do something like this using the OR pattern:
let doIt (ex:Example) =
match ex with
| Foo(_) -> 0
| NoValue -> -1
| Bar(i) | Baz(i) | Qux(i) -> i;;
It does, however, eliminate the duplication of all of the (possibly) complex portion of that case.
For the sake of further illustration, you can also do this even if your cases don't match exactly like so:
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
Upvotes: 11
Reputation: 41290
You can also change the view of discriminated unions using 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
But if three cases should be handled in the same way repetitively, you should consider to refactor your 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
Upvotes: 11