I have the following:
type union1 =
| Case1 of string
| Case2 of int
let union1s = seq { for i in 1..5 do yield case2 i }
How do I change union1s
to a sequence of type seq<int>
?
Something like:
let matchCase item =
match item with
| Case1 x -> x
| Case2 x -> x
let case2s = Seq.map matchCase union1s
This attempt does not work because matchCase can not return two different types.
The suggested answers have the same problem (if I understand correctly)
let matchCaseOpt = function
| Case1 x -> Some x
| Case2 x -> Some x
| _ -> None
let case2s = Seq.choose matchCaseOpts unions1s
The expression Some x expects expects type Option string in the match for Case2
I have solved my particular use-case by using a DU of sequences.
type Union1s =
| Case1s of seq<string>
| Case2s of seq<int>
A discriminated union is a union data structure that holds various objects, with one of the objects identified directly by a discriminant. The discriminant is the first item to be serialized or deserialized. A discriminated union includes both a discriminant and a component.
Discriminated unions are useful for heterogeneous data; data that can have special cases, including valid and error cases; data that varies in type from one instance to another; and as an alternative for small object hierarchies.
The concept of discriminated unions is how TypeScript differentiates between those objects and does so in a way that scales extremely well, even with larger sets of objects. As such, we had to create a new ANIMAL_TYPE property on both types that holds a single literal value we can use to check against.
Advertisements. Unions, or discriminated unions allows you to build up complex data structures representing well-defined set of choices. For example, you need to build an implementation of a choice variable, which has two values yes and no. Using the Unions tool, you can design this.
You are assuming your sequence contains not a single case1, so if this is not true you need to throw an exception.
let matchCase item =
match item with
| Case1 x -> failwith "Unexpected Case1"
| Case2 x -> x
let case2s = Seq.map matchCase union1s
An alternative approach, if you are not sure the sequence contains always the same case is to use an Option
let matchCase item =
match item with
| Case1 x -> None
| Case2 x -> Some x
Then it depends on how you will handle these cases, you can just filter out the None
values using Seq.choose instead of Seq.map as shown on the other answer.
Which approach to follow depends if you consider having an argument with Case1s an exceptional case or part of the logic of your program. There was a question regarding this F#: Some, None, or Exception? recently.
Using a DU of sequences is correct if you are not mixing Cases, that way your DU Type restrict your domain to the actual cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With