I think this article makes the "sum" and "product" terms out to be very complicated, when in fact it's quite simple. If we have two enums<p><pre><code> enum Bool {
True,
False
}
enum Status {
Waiting,
Successful,
Failed
}
</code></pre>
We can combine them into a product type, like a tuple, or a sum type, like a union.<p><pre><code> type Product = (Bool, Status)
type Sum = Bool | Status
</code></pre>
Now, we ask ourselves, what are the valid values of type Product?<p><pre><code> (True, Waiting)
(True, Successful)
(True, Failed)
(False, Waiting)
(False, Successful)
(False, Failed)
</code></pre>
There are two Bool values, and three Status values, so there are 2×3=6 values for the product of Bool and Status. Now, what about the Sum type?<p><pre><code> True
False
Waiting
Successful
Failed
</code></pre>
We have 2+3=5 total values for the sum of Bool and Product.<p>Now, obviously, this math doesn't quite work out for types with infinite values, like strings or bigints or arrays, but that's where the analogy comes from.<p>If you extend this further, you can even figure out what an exponential type would be: the exponential type Bool^Status is a function that takes a Status as its argument and returns a Bool.