Is it possible to pass discriminated union tags as arguments?

前端 未结 5 1400
不思量自难忘°
不思量自难忘° 2020-12-31 17:04

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:



        
5条回答
  •  北海茫月
    2020-12-31 17:38

    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-Pigs 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.

提交回复
热议问题