I can imagine that in f# this refactor would be a lot simpler and would allow me to have a case of empty that I could propagate around and handle transparently.
In F#, None is a subtype of the Option<Foo> union type, which is different from the plain Foo type and from the other subtype Some Foo. If you change a function that used to return a plain Foo into one returning Option<Foo>, every place in your code where that function is consumed will throw a compile error until you edit it to unwrap and handle the distinct Some Foo and None subtypes.
The interface of this generic container only allows you to interact with the (potentially) wrapped value in a way that is type safe. That doesn't completely eliminate having to think about how the business logic should differ for missing values, but it ensures that you'll never get a null pointer exception.
The type system in F# can guarantee that an instance of a class can never be null and you can always refer to it safely.