So, after reading the spec, the first hint here
b) Types with a null value as an abnormal value. These are types that do not allow a null literal, but have a null value as an abnormal value.
Types in this category:
o All types of F # list, record, tuple, function, class and interface.
o All union types F #, except those whose null value is equal to the normal value (as discussed in the next section).
For these types, the use of a null literal is not directly permitted. However, strictly speaking, you can generate null for these types using certain functions, such as Unchecked.defaultof. For these types, null is considered an abnormal value. The behavior of operations with respect to zero values ββis defined in Β§ 6.9.
This seems to suggest that when passing in a null value for your union, there might be some undefined behavior, since the value is "abnormal", section 6.9 is not particularly useful
Looking at the definition for _
, it seems that you are right that this is a mistake - she states
7.1.7 Substitution Patterns
Sample _ is a wildcard and matches any input. For example:
allow categorization x =
match x with | 1 -> 0 | 0 -> 1 | _ -> 0
I think the most relevant hints, but later, where compiled methods for DU are listed
8.5.3 Compiled union type form for use with other CLI languages
The compiled union type U will have:
Β· One CLI property for a static UC getter for each null union of case C. This will get a singleton object representing this case.
. One CLI-nested UC type for each case with zero union C. This type will have instance properties Item1, Item2 .... for each field of the union case, or one instance property object if it is only one field. Compiled type joins with one case do not have a nested type. Instead, the type of union itself plays the role of the type of corps.
Β· One static UI.NewC CLI method for each case that is not associated with a null union C. This will build an object for this case.
. One u.IsC CLI instance property for each C case, which returns true or false for the case.
. One property of the u.Tag CLI instance for each C case that selects or evaluates an integer tag that matches the case.
From this, you can see that all validation methods are instance methods that require nonemptiness. The sine of null
is "abnormal", the generated code does not check, so it throws.
I think you could argue that this is an infact error based on the definition of _
. However, to fix it, you will need to insert null checks before each DU pattern matching check, which will significantly reduce the code, so I doubt it will be fixed.