DEV Community

Jose Gonzalez
Jose Gonzalez

Posted on

When to use a Discriminated Union vs Record Type in F#

As my functional programming adventure continues, I come across terms I'm not familiar with. Today, we'll look at when to use a Discriminated Union vs Record Type.

I strongly believe on the best way to learn something is to teach it to someone else.

It will solidify your knowledge.

(I'm learning F# and before I become too good at it, I'd to share my beginner's notes with you. Hopefully, it helps you to understand F# and functional programming.)

Discriminated Union

Let's skip all the boring jargon out there. Here's the simplest explanation I could find

possible [data] values for which can be enumerated.

Some examples:

type Status =
| Active
| Inactive
| Disabled

type Answer =
| Yes
| No

Answer up above can only be Yes or No.

It can't be anything else other than those two specific values.

It seems to work similar to C# enums.

Record Type

Skipping all the jargon again:

[used] for complex data which is described by several properties, like a database record or some model entity

These are the equivalent of your classes in a language like C#. But I feel like they are more structs than classes.

Some examples:

type User = { FirstName: string; LastName : string; Age: Int; }


type Cookie = { Name: string; Color: string; }

When to use a Discriminated Union vs Record Type

Think of it as a Record is 'and', while a discriminated union is 'or'.

This is the key.

Record = and
Discriminated Union = or

Example:

type MyRecord = { myString: string
                  myInt: int }

The following value can either be a string OR an int, but not both:

type MyUnion = 
| Int of int
| Str of string

Here's another discriminated union example in a fictitious game:

type Game =
| Title
| Ingame
| Endgame

You can only be in one area at the time.

You can't be in the Title screen and be Ingame.
You can't be in the Ingame and be at Endgame.

Think of this as options for your radio buttons.

Closing Thoughts

If you skipped all the way to the end, make sure you read the When to use a Discriminated Union vs Record Type section at the very least.

Discriminated Union sounds very intimidating. But think of it asL multiple options your value can be.

The simplest comparison is options for your radio buttons.

What do you think? How would you define a discriminated union and a record type in F#?

Originally posted at:
http://www.mindbodysouldeveloper.com/

Resources

Top comments (2)

Collapse
 
alexanderlindsay profile image
Alexander Lindsay • Edited

This is a good explanation of the two types.

Both types are very useful on there own, but things get interesting when you combine them. Also, there are choices for how to combine them.

For example, in a card game of sorts is there a record type Card that has a discriminated union CardType or does the union contain the records?

See the following:

type CardType
| Attack of int
| Defense of int

type Card = {
  cost: int;
  type: CardType;
}
Enter fullscreen mode Exit fullscreen mode

or

type AttackCard =
{
  strength: int;
  cost: int;
}

type DefenseCard =
{
  mitigation: int;
  cost: int;
}

type Card
| Attack of AttackCard
| Defense of DefenseCard
Enter fullscreen mode Exit fullscreen mode

I think it depends on how the cards are going to be used. If the second pattern is followed then every interaction with a card will first have to handle the card type. If you need the cost before the type something like the first pattern should work.

Collapse
 
josegonz321 profile image
Jose Gonzalez

Excellent example. You are right, it depends how you are going to use your cards.

There is no silver bullet but it's always good to know that there are options available.

Thank you for sharing your thoughts on this.