I love everything about this! I think a lot of code could benefit from restructuring via ADTs, and ser/deser is an important piece of that story. But I suppose I do have one nitpick.
Using a fallback for asymmetric fields in sum types seems off to me, albeit pragmatic. If the asymmetric fields for product types use an Option<T>, and Option is basically a sum of a T and a Unit, a close dual is a product (struct/tuple) of a T and the dual of Unit (a Nothing type, eg. one with no instantiable values, such as an empty enum).
I think this would provide similar safety guarantees, as a writer couldn't produce a value of an added asymmetric sum type variant, but a reader could write handling for it (including all subfields besides the Nothing typed one)?
There's one perspective (popular in funtional programming circles) that says data structures simply _are_ a special sort of function; that is, one that take no arguments.
Really, in practice this means data is a partially applied, curried, identity function. Put something in, get the same thing out later, acting as memoization.
The card game example you propose is a pretty apt one.
One might have any number of cards in a given hand, with any number of varying properties (like for standard 52 card decks, suit and rank). To keep a fixed size feature vector as the input for a neural net, one approach is to have a representation that treats every distinct possible card as a single input feature in the vector, with value representing whether it is currently in a given player's hand or not (0 or 1).
This of course falls apart a bit when looking at card games where multiple copies of the same card can exist. If you just scale up the input feature values proportionally to the duplicate card count, you might assume a linear effect of those duplicate cards where a nonlinear effect exists. TDGammon's representation for Backgammon solves a similar issue, a similar way, for representing how many stones exist on a given point (if I recall correctly, some version of it cares about 0, 1, 2, or 3+ as distinct possibilities, represented effectively as different features per point). Still, as a first approximation, this does work for a decent swath of games (and abstracts the ordering of cards away).
It seems like this article's approach involves a good deal of having the neural net recognize symmetries like this automatically.
As others here have hinted at, while NNT and NNH are both extremely useful concepts, they (deliberately) leave the consideration of whether a treatment's level of effectiveness, or the magnitude of a harmful side effect, subjective. When, after all, should a negative side effect be counted as "harm"? This is especially true for NNH; there are usually far more possible (helpful or harmful) side effects than the one intended remedy for the ailment, for a given drug.
As an example, in one study, for elderly patients the NNT of a number of (admittedly different) sedative hypnotics was 13, while the NNH was 6 [1]. From that alone, you'd probably rightfully avoid using them! But for certain populations who have chronic insomnia, the benefits may still outweigh the risks.
Of course, there are ways to (less subjectively albeit still subjectively) quantify harm, and these get used to keep "harm" comparable to "treatment". But it can definitely be more of an art than an exact science.
Using a fallback for asymmetric fields in sum types seems off to me, albeit pragmatic. If the asymmetric fields for product types use an Option<T>, and Option is basically a sum of a T and a Unit, a close dual is a product (struct/tuple) of a T and the dual of Unit (a Nothing type, eg. one with no instantiable values, such as an empty enum).
I think this would provide similar safety guarantees, as a writer couldn't produce a value of an added asymmetric sum type variant, but a reader could write handling for it (including all subfields besides the Nothing typed one)?