|
|
|
|
|
by gnosek
2021 days ago
|
|
I agree with all your other points but > > We can’t perform arithmetic on an Option<int> any more than we could on a List<int>. > Why not? One sensible definition is
(...) It's not the only sensible definition. It would be equally sensible to implement it as: Some(x) + Some(y) => Some(x+y)
Some(x) + None => Some(x)
None + Some(y) => Some(y)
None + None => None
|
|
It can be interesting to see what other languages do in this situation. For example, C# got nullable value types in version 2, and had to decide what to do with operators in a similar vein (including pre-existing overloaded operators in user code) - they called it "lifting":
https://docs.microsoft.com/en-us/dotnet/csharp/language-refe... https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
You might notice that it almost, but not quite, has consistent semantics: null means "unknown", which is particularly obvious from Booleans: (true | null) is true, and (false & null) is false, but (true & null) and (false | null) are both null. However, comparison operators aren't consistent: you'd expect x == null to be null if it meant "unknown", but the language will always give you either true or false; and ditto for relative comparisons. This last one means that it's possible for (x == y), (x < y), and (x > y) to all be false.
What's interesting is that, in practice, it's rare to see reliance on any of this behavior in idiomatic C# code - "null" is usually used as "missing", not as "unknown", so all this magic is, at best, irrelevant, and at worst, actively harmful (because it defers a logic error).