I was contemplating suggesting impl<T:Add<U>,U> Add<Option<U>> for Option<T>, but unfortunately (IMHO) the fact that Option was made Ord prevents that from being done consistently for the comparison operators, so I don't know if it's a good idea for the other operators.
Looks like nightly can apparently already make a lifting adapter:
#![feature(unboxed_closures)]
#![feature(fn_traits)]
fn main() {
let f = OptionLift(std::ops::Add::add);
assert_eq!(f(Some(2), Some(3)), Some(5));
let g = OptionLift(std::ops::Neg::neg);
assert_eq!(g(Some(2)), Some(-2));
}
struct OptionLift<F>(F);
impl<F:FnOnce<(T0,)>,T0> FnOnce<(Option<T0>,)> for OptionLift<F> {
type Output = Option<F::Output>;
extern "rust-call" fn call_once(self, (a0,): (Option<T0>,)) -> Self::Output {
Some((self.0)(a0?))
}
}
impl<F:FnOnce<(T0,T1,)>,T0,T1> FnOnce<(Option<T0>,Option<T1>,)> for OptionLift<F> {
type Output = Option<F::Output>;
extern "rust-call" fn call_once(self, (a0,a1,): (Option<T0>,Option<T1>,)) -> Self::Output {
Some((self.0)(a0?,a1?))
}
}