Is it possible to pass discriminated union tags as arguments?
discriminated-union, f#, pattern-matching
Solution
Discriminated unions works best if there is no semantic overlap between the cases.
In your example, each case contains the same component with the same meaning, a `string` indicating "the name of the animal". But that's a semantic overlap! The discriminating union will then force you to make distinctions you don't want to: You don't want to be forced to discriminate between the "name of a pig" and the "name of a cow"; you just want to think of "the name of an animal".
Let's make a type that fits better:
type Animal = Pig | Cow | Fish
type Pet = Animal * string
let animals = [(Pig, "Mike"); (Fish, "Eve"); (Pig, "Romeo")
With that type, filtering out non-`Pig`s is a one-liner:
animals |> List.filter (fst >> (=) Pig)
If not every animal has a name, use an option type:
type Pet = Animal * string option
You would use a discriminated union for your animals if you knew that, say, every `Pig` has a name, but no `Fish` does: those cases have no overlap.
Problem
Is it possible to pass the type of a discriminated union tag to another function so it can use it for pattern matching? Non working example of what I mean: ``` type Animal = Pig of string | Cow of string | Fish of string let animals = [Pig "Mike"; Pig "Sarah"; Fish "Eve"; Cow "Laura"; Pig "John"] let rec filterAnimals animalType animals = if animals = [] then [] else let rest = filterAnimals animalType (List.tail animals) match List.head animals with |animalType animal -> animal::rest // <- this doesn't work |_ -> rest printfn "%A" (filterAnimals Pig animals) ```