I am getting into Functional programming from C#. Because of my deep and detailed knowledge of C#, of course, I've chosen for my first functional language F# and tried to invest my time to learn it.
Now I am at the step where I need to understand what are Discriminated Unions and why it is important and why we actually need it?!
I've made really a lot of research
But the problem of mentors, lecturers, articles and blog posts is that people are actually trying to describe/teach us Discriminated Unions with a lot of functional programming terms which is of course very non-understandable for us, people who's whole background is OOP and just a little LINQ, Expressions and high-order functions.
I am very new in the Functional world and my brain is full of that OOP mindset so it is very hard to just understand that concept from that point of view.
If you actually google it, you will get that type of response :
Discriminated Unions # You can combine singleton types, union types, type guards, and type aliases to build an advanced pattern called discriminated unions, also known as tagged unions or algebraic data types. Discriminated unions are useful in functional programming.
And it really not makes any sense in my mind. So please in a human and normal way tell me what is Discriminated Union, why we need it? What can be compared to the OOP world? (because it will really help me)
Thank you.
Discriminated unions are a bit like class hierarchies in OOP. The classic example in OOP is something like an animal, which can be either a dog or cat. In OOP, you would represent this as a base class with some abstract methods (e.g. MakeAnimalNoise
) and concrete subclasses for dogs and cats.
In functional programming, the matching thing is a discriminated union Animal
with two cases:
type Animal =
| Dog of breed:string
| Cat of fluffynessLevel:int
In OOP, you have virtual methods. In FP, you write operations as functions using pattern matching:
let makeAnimalNoise animal =
match animal with
| Dog("Chihuahua") -> "woof sqeek sqeek woof"
| Dog(other) -> "WOOF"
| Cat(fluffyness) when fluffyness > 10 -> "MEEEOOOOW"
| Cat(other) -> "meow"
There is one important difference between the FP and OOP methods:
This might seem strange if you are coming from an OOP background. When discussing classes in OOP, everybody emphasizes the need for extensibility (by adding new classes). In practice, I think you need both - and so it does not matter much which direction you choose. FP has its nice benefts, just as OOP has (sometimes).
This is, of course, a completely useless example. For a more realistic discussion of how this is useful in practice, see Scott Wlaschin's excellent Designing with Types series.