> It really depends on what the meaning of None is.
Exactly. This will generally be application specific so we can't choose The One Right Definition for adding `Option<i32>`s.
> Yours make sense if it means "zero", but that's far less useful.
Not in my experience but I agree there are different situations. Personally, I'd default to `Option<i32>::None` meaning "no number there, so just skip it"[1] and prefer `Result<i32, E>::Err` to denote "there should be a number here but we don't have one", which would behave like a SQL NULL (propagate in all calculations).
1. What's the length of data in a header-only packet? I wouldn't say it's zero, especially when trying to fit a read() like API on top of a framed protocol (read() returning Ok(0) marks the end of file).
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).