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

Functional Validation in F# Using Applicatives

Learn how to implement functional validation in F# using applicatives. Handle multiple errors elegantly with Railway-Oriented Programming and concise functional patterns.

Blog 5/18/22

Introduction to Functional Programming in F#

Dive into functional programming with F# in our introductory series.

Blog

Function Composition in F# with Unfriendly Functions

Explore how to handle unfriendly library functions in F# by using wrappers, higher-order functions, or inline solutions to keep pipelines clean and functional.

Blog

Using GCP Cloud Functions with F#

Learn how to build and test Google Cloud Functions in F#, using dependency injection, configuration, and pub/sub messaging for real-world cloud apps.

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.

young business woman smiles it jobs timetoact group
Jobs

(Senior) Consultant SAP FI (f/m/d)

Walldorf Consulting | Walldorf | Full-time & Permanent employment | Available now

two colleagues working together it jobs timetoact group
Jobs

(Senior) Consultant SAP MM (f/m/d)

Walldorf Consulting | Walldorf | Full-time & Permanent employment | Available now

young business man smiles it jobs timetoact group
Jobs

(Senior) Consultant SAP SD (f/m/d)

Walldorf Consulting | Walldorf | Full-time & Permanent employment | Available now

team of young colleagues it jobs timetoact group
Jobs

(Senior) Consultant SAP CO (f/m/d)

Walldorf Consulting | Walldorf | Full-time & Permanent employment | Available now

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

Bleiben Sie mit dem TIMETOACT GROUP Newsletter auf dem Laufenden!