Bottom Type in F#
It is ALMOST possible to express the bottom type in F#.
The bottom type is the type that has no values. It is useful as the return type of a function when every execution either does not terminate or throws an exception. Some languages include the bottom type. The suggestion for F# to add the bottom type was declined. Interestingly, the suggestion for C# to add the bottom type lives on.
Nevertheless, it is possible to define the bottom type in F#. Here is how I would do it.
1linktype Bottom = private Bottom of Bottom
My original thought was to omit of Bottom
and then have this line be alone in its module (so that a public function does not provide access to this private case constructor). Then I read the suggestion to include of Bottom
in this post on Reddit from three years ago. By including of Bottom
, this discriminated union is a recursive type but lacks a base case. As such, it is clear from this one line that it is impossible to obtain an instance of Bottom
.
In addition to having no values, there is another property of the bottom type. In subtyping systems, it is a subtype of all types. That is the motivation for the name "bottom". It sits at the bottom of the type hierarchy. My bottom type does not have this property. I think the suggestion for F# to add the bottom type was specifically requesting this feature.
Added 2020-09-23
I just realized that this does not work as I had intended because Unchecked.defaultof<>
exists.
1link> type Bottom = Bottom of Bottom;;
2linktype Bottom = | Bottom of Bottom
3link
4link> Unchecked.defaultof<Bottom>;;
5linkval it : Bottom = <null>
This definition of Bottom
is a reference type, and reference types can be null
. Now the recursive nature is a detriment. I was aiming for a type with zero values, but I actually created a type with infinitely many values since <null>
, Bottom <null>
, Bottom (Bottom <null>)
, and so on are a rather direct translation of the Church numerals.
If we change Bottom
to a struct
, then the compiler complains about the recursive definition.
1link[<Struct>]
2linktype (*~*)Bottom~~~~~~(*~*) = Bottom of Bottom
Error FS0954 This type definition involves an immediate cyclic reference through a struct field or inheritance relation
After removing of Bottom
to make the type non-recursive, both the reference and struct variants of the definition now have exactly one value. This is now just a more verbose way to define the unit type, the type with just one value, which F# already has.
My six-year-old daughter has been saying lately that "there is no perfect; there is only good enough". I am going to take her advice here and be content with this approximation of the theoretically perfect bottom type in the pragmatic language that is F#.
The tags feature of Coding Blog Plugin is still being developed. Eventually the tags will link somewhere.