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.
1type 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
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.
I just realized that this does not work as I had intended because
F# Interactive1> type Bottom = Bottom of Bottom;;2type Bottom = | Bottom of Bottom34> Unchecked.defaultof<Bottom>;;5val 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
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.
1[<Struct>]2type (*~*)Bottom~~~~~~(*~*) = Bottom of Bottom
Error FS0954 This type definition involves an immediate cyclic reference through a struct field or inheritance relation
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.