Is there a simple way today to get the other kind lift, which turns a binary operation on T into a binary operation on Option<T>, respecting the new identity element None?
fn lift<T, F: FnOnce(T, T) -> T>(
f: F, left: Option<T>, right: Option<T>) -> Option<T> {
match (left, right) {
(None, right) => right,
(left, None) => left,
(Some(left), Some(right)) => Some(f(left, right)),
}
}
This does the right thing for std::cmp::min, std::cmp::max. I think this is the expected lift from a semigroup T into a monoid T ⊍ {None}. But it is curiously absent from Haskell, Standard ML, and Java.
This is also the lift you need if you want to fold on a binary operation which does not have a natural zero element to start with, so the omission is even more curious.