So, I’ve run across a better motivation: Futures. The futures-rs crate uses Results everywhere, even in cases that can’t error. Furthermore, futures-rs often accepts Results as function arguments (most rust crates just return them).
Motivation
Typing Ok(value) everywhere is annoying and makes it harder to understand what’s going on in the code. Whenever I see an Ok(...) I immediately assume that something can fail and start looking for the Errs.
Motivating Examples
For example, in
@alexcrichton and @stepancheg considered making stream::repeat take a Result but decided to take a value directly (possibly adding a stream::repeat_err method in the future) because the common case, stream::repeat(Ok(value)), isn’t very ergonomic.
However, if we had a From<T> for Result<T, E> implementation, one could implement fn repeat<T, E, R: Into<Result<T, E>>>(item: R) -> impl Stream<Item=T, Error=E>. The user could call either stream::repeat(value) or stream::repeat(Err(e)). This would also apply to other helper functions like stream::once and done.
Additionally, one could use this as described in my first post to simplify using many of the adapters in futures-rs. For example, you could replace:
my_stream.for_each(|item| {
println!("{}", item);
Ok(())
});
with:
my_stream.for_each(|item| {
println!("{}", item)
});
Drawbacks
One potential (big) drawback is type inference. Depending on the use-case, the error may be unconstrained.
Alternatives
-
An alternative is to implement impl<T> From<T> for Result<T, !>. This would avoid the type inference problem. Unfortunately, it would make this feature less useful (maybe? I’m not actually sure it would be a huge problem and the benefits may outweigh the drawbacks).
-
Default "impl"s (default type parameters for selecting trait implementations (type inference hints?)). That is, impl<T, E=!> From<T> for Result<T, E>. However, this would require a lot of thought and design work and I kind of doubt it will happen any time soon.