Suppose I have a DU like so:
type DU = Number of int | Word of string
And suppose I create a list of them:
[Number(1); Word("abc"); Number(2)]
How can I write a function that would return true for a list of DUs where all the elements are the same case. For the above list it should return false.
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.
Union types are used when a value can be more than a single type. Such as when a property would be string or number .
The general approach I'd use here would be to map the union values into tags identifying the cases, and then check if the resulting set of tags has at most one element.
let allTheSameCase (tagger: 'a -> int) (coll: #seq<'a>) =
let cases =
coll
|> Seq.map tagger
|> Set.ofSeq
Set.count cases <= 1
For the tagger function, you can assign the tags by hand:
allTheSameCase (function Number _ -> 0 | Word _ -> 1) lst
or use reflection (note that you might need to set binding flags as necessary):
open Microsoft.FSharp.Reflection
let reflectionTagger (case: obj) =
let typ = case.GetType()
if FSharpType.IsUnion(typ)
then
let info, _ = FSharpValue.GetUnionFields(case, typ)
info.Tag
else -1 // or fail, depending what makes sense in the context.
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