Domain modeling in F#

How often do you see an email represented as a string? Or a currency field being a decimal type? Did you ever consider that something is wrong with this approach?

That's the usual manifestation of primitive obsession. It occurs when you use primitive types like strings or decimals for domain modeling. I argue that the reason behind it is laziness and being scared of introducing too many types.

Type aliases and record types

Luckly, F# got you covered!
Aliases and records make creating new types both enjoyable and easy. Have a look at this code:

type StationName = StationName of string
type StationCode = StationCode of string

type Station =
    { Name: StationName
      StationCode: StationCode }

We just defined Station that consists of a name and a code.
It's plain English! I like how obvious and readable it is. In the end, we don't have to care what's behind these fields. That should be an implementation detail.

If someday we want to change StationCode to a number instead of a string, we do it in one place, and the rest of the code should stay the same.
Yes, it's that helpful!

Custom types requires custom code

There is a caveat, of course.
We can't use the usual string methods on such alias types.
How to deal with this? I will try to address this in another post.