Convert nulls to Options in F# with Option.ofObj
Date: 2024-05-31 | create | tech | fsharp |
Nulls are the billion dollar mistake and a common source of problems in many systems. They break because code assumes something is non null but in reality it can be null and yet the technology doesn't surface this info - thus an implicit case unhandled and leading to breakages.
F# tries to solve for this by making nulls explicit - values can be options meaning it's either Something (Some) or Nothing (None). This coupled with F#'s exhaustive pattern matching helps make this implicit case explicit - you must handle both Some and None cases.
Despite this design choice there are still many ways nulls may enter your system - usually at the edges where we interface with other systems like network requests, DB calls, or calls into other langs (like C#).
In this post we'll explore an easy method for converting these nulls into options to make this common task a bit less tedious.
Converting Nulls to Options
We want to convert nulls to options because it makes the fact that this thing could be None explicit and allows the F# type system to help us out in catching these cases.
A naive approach (and what I've been doing for a long time) is to write your own converter with a simple match statement:
match maybeNull with
| v when isNull v -> None
| v -> Some v
This works fine but can get cumbersome if you decide to write it out a lot instead of using a single util function.
Note: This is what I did in my most recent project to get a web request's IP address - it works but the code is verbose.
Simple null to Option with Option.ofObj
Luckily F# includes a helper function to do this for us - Option.ofObj
(official docs). This basically does the same thing - just without us writing the match statement ourselves.
Shoutout to Peter and Ian on Twitter for pointing this out to me!
maybeNull
|> Option.ofObj
You can play around with both of these and see the results in this example Replit.
Note: You can also see in the source code (github) that the implementation of Option.ofObj
is internally doing the same match statement.
Next
I'm still learning a lot about F# and new ways of doing things. I only build with F# in my free time so don't get as much feedback (via code review etc) as I do in other langs I use for my job. This has already made my code much simpler so hopefully it does the same for yours.
Q: How are you dealing with nulls at the edges of your systems? Any techniques you've found particularly simple or powerful?
If you liked this post you might also like:
Want more like this?
The best / easiest way to support my work is by subscribing for future updates and sharing with your network.