Understanding F# Type Aliases

In this post, we discuss the difference between F# types and aliases that from a glance may appear to be the same thing.

I recently wrote a single case discriminated union which is what I wanted but was also confused why it didn't behave like a type alias and then learnt that these two are different things.

type CustomerId = int

type CustomerId = CustomerId of int

I was aware of both syntaxes and from a quick scan they look the same however they behave differently and rightly so. As I travel the F# road there is more emphasis on creating types for your functions. I have used this approach in C# to enforce type discrimination but it seems less prevalent in the mainstream from my experience. For example think of this:

public string DoSomething(string name, int age, string address)
{
  ...
}

This would become:

public string DoSomething(Name name, Age age, Address address)
{
  ...
}

This goes someway for example to disallow passing any random string or int value to methods throughout your domain. If everything is a int or string or any other primitive type there's nothing stopping you calling the above method like so:

DoSomething("10 Downing St", 21, "Jon for PM").

This would compile fine and only at runtime are you likely to spot the issue.

So with this design in mind I wanted to create a type and away I went and created type CustomerId = CustomerId of int. This type was passed into a function and I needed to get the underlying value to convert to SQL. For some reason I had type CustomerId = int in my mind so I called ToString() on my type assuming that would get the underlying value. In fact what it returned was "CustomerId 2" ie/ a string-ified .NET object. This didn't raise it's head until runtime however as my SQL statement failed. Now if I had created my type as an alias and not a type eg. type CustomerId = int it would have worked fine. However, a type alias is just that, an alias and does not give you the design I described above. For example,

type Name = string
type Age = int
type Address = string


let doSomething (name:Name) (age:Age) (address:Address) =
    age.ToString()

I can call the function like so doSomething "Jon for PM" 21 "10 Downing St" and also doSomething "10 Downing St" 21 "Jon for PM" and both are valid at compile time but you haven't achieved what you set out to achieve. What you actually want is:

type Name = Name of string
type Age = Age of int
type Address = Address of string

let doSomething (name:Name) (age:Age) (address:Address) =
    age.ToString()

To call this function you have to be much more explicit:

let res = doSomething (Name("Jon for PM")) (Age(21)) (Address("10 Downing St"))
printfn "%s" res

There's no way to mix up the arguments however we are still at the original issue I faced, the return value will be a string-ified .NET object. In F# to get the inner value out you have to create a module to take your type and extract the value:

module Age =
       let value (Age input) = input

We can then amend our function to call it like so:

let doSomething (name:Name) (age:Age) (address:Address) =
    (Age.value age).ToString()

Now this might seem a bit of a pain but that is because we have type safety and have to be very explicit if we want to expose that value which is no bad thing really.

Blog 7/21/20

Understanding F# applicatives and custom operators

In this post, Jonathan Channon, a newcomer to F#, discusses how he learnt about a slightly more advanced functional concept — Applicatives.

Blog 3/22/23

Introduction to Functional Programming in F# – Part 8

Discover Units of Measure and Type Providers in F#. Enhance data management and type safety in your applications with these powerful tools.

Blog 12/22/22

Introduction to Functional Programming in F# – Part 6

Learn error handling in F# with option types. Improve code reliability using F#'s powerful error-handling techniques.

Blog 11/30/22

Introduction to Partial Function Application in F#

Partial Function Application is one of the core functional programming concepts that everyone should understand as it is widely used in most F# codebases.In this post I will introduce you to the grace and power of partial application. We will start with tupled arguments that most devs will recognise and then move onto curried arguments that allow us to use partial application.

Blog 9/13/22

Introduction to Functional Programming in F# – Part 2

Explore functions, types, and modules in F#. Enhance your skills with practical examples and insights in this detailed guide.

Blog 10/1/22

Introduction to Functional Programming in F# – Part 4

Unlock F# collections and pipelines. Manage data efficiently and streamline your functional programming workflow with these powerful tools.

Blog 7/12/23

Introduction to Functional Programming in F# – Part 11

Learn type inference and generic functions in F#. Boost efficiency and flexibility in your code with these essential programming concepts.

Blog 5/18/22

Introduction to Functional Programming in F#

Dive into functional programming with F# in our introductory series. Learn how to solve real business problems using F#'s functional programming features. This first part covers setting up your environment, basic F# syntax, and implementing a simple use case. Perfect for developers looking to enhance their skills in functional programming.

Blog 3/22/23

Introduction to Functional Programming in F# – Part 9

Explore Active Patterns and Computation Expressions in F#. Enhance code clarity and functionality with these advanced techniques.

Blog 9/27/22

Creating solutions and projects in VS code

In this post we are going to create a new Solution containing an F# console project and a test project using the dotnet CLI in Visual Studio Code.

Blog 12/22/22

Introduction to Functional Programming in F# – Part 7

Explore LINQ and query expressions in F#. Simplify data manipulation and enhance your functional programming skills with this guide.

Blog 5/17/23

Introduction to Functional Programming in F# – Part 10

Discover Agents and Mailboxes in F#. Build responsive applications using these powerful concurrency tools in functional programming.

Blog 8/8/23

Introduction to Functional Programming in F# – Part 12

Explore reflection and meta-programming in F#. Learn how to dynamically manipulate code and enhance flexibility with advanced techniques.

Blog 3/11/21

Introduction to Web Programming in F# with Giraffe – Part 2

In this series we are investigating web programming with Giraffe and the Giraffe View Engine plus a few other useful F# libraries.

Blog 8/10/23

Machine Learning Pipelines

In this first part, we explain the basics of machine learning pipelines and showcase what they could look like in simple form. Learn about the differences between software development and machine learning as well as which common problems you can tackle with them.

FAQs Fragen G Suite Workspace Google
Lösung

Google Workspace FAQs

Google Workspace is not always self-explanatory. Here we answer possible questions. CLOUDPILOTS is happy to help with consulting and migration to the Cloud!

Blog 9/15/22

Introduction to Functional Programming in F# – Part 3

Dive into F# data structures and pattern matching. Simplify code and enhance functionality with these powerful features.

Blog 3/12/21

Introduction to Web Programming in F# with Giraffe – Part 3

In this series we are investigating web programming with Giraffe and the Giraffe View Engine plus a few other useful F# libraries.

Blog 10/11/22

Introduction to Functional Programming in F# – Part 5

Master F# asynchronous workflows and parallelism. Enhance application performance with advanced functional programming techniques.

Blog 12/3/21

Using Discriminated Union Labelled Fields

A few weeks ago, I re-discovered labelled fields in discriminated unions. Despite the fact that they look like tuples, they are not.

Bleiben Sie mit dem TIMETOACT GROUP Newsletter auf dem Laufenden!