|
|
|
|
|
by nailer
1439 days ago
|
|
The compiler would enforce Number-ness every time I try and run a function that takes a number, right? Wouldn’t I still have to check for NoScore? > a sum type with units of Score(Int) and NoScore won't allow assignments of any other "null" instances. I get this part - I wouldn’t be able to assign ‘NewBornBaby’ (my name null) to ‘NoScore’ (my score null) |
|
> Wouldn’t I still have to check for NoScore?
No, because you differentiate between the sum type (e.g. Maybe in Haskell) and the number type at compile time. It's a small distinction - there will still be one or two places where you ask "is this a Maybe-score, or a Just-Score, or a No-Score", but the upside is that in all places you are very clear if a No-Score is possible, and you can't confuse the value with the error signal.
I.e. if you pass maybe-scores to something that computes the mean, you'll get a compiler error. The writer of the mean function doesn't need to care you've overloaded an error value onto your numbers.
The compiler support is the important part. Languages like C/C++ know sum-types just fine. They usually surface as sentinel values (NULL for ptrs, -1 for ints, etc) or unions with type fields. The stdlib offers it as std::optional<T>. As you progress along that spectrum, you get increasing compiler support there, as well.
One could even argue that sentinel values are a slightly better choice than Go's pairs, because they are closer to being sum-types than the strict product type that is go's (result, error) tuple - at least sentinels can't be simultaneously carrying a valid value and an error.