It would be nice if Rust\'s Option provided some additional convenience methods like Option#flatten and Option#flat_map, where f
These probably already exist, just as different names to what you expect. Check the docs for Option.
You'll see flat_map more normally as and_then:
let x = Some(1);
let y = x.and_then(|v| Some(v + 1));
The bigger way of doing what you want is to declare a trait with the methods you want, then implement it for Option:
trait MyThings {
fn more_optional(self) -> Option<Self>;
}
impl<T> MyThings for Option<T> {
fn more_optional(self) -> Option<Option<T>> {
Some(self)
}
}
fn main() {
let x = Some(1);
let y = x.more_optional();
println!("{:?}", y);
}
For flatten, I'd probably write:
fn flatten<T>(opt: Option<Option<T>>) -> Option<T> {
match opt {
None => None,
Some(v) => v,
}
}
fn main() {
let x = Some(Some(1));
let y = flatten(x);
println!("{:?}", y);
}
But if you wanted a trait:
trait MyThings<T> {
fn flatten(self) -> Option<T>;
}
impl<T> MyThings<T> for Option<Option<T>> {
fn flatten(self) -> Option<T> {
match self {
None => None,
Some(v) => v,
}
}
}
fn main() {
let x = Some(Some(1));
let y = x.flatten();
println!("{:?}", y);
}
Would there be a way to allow flatten to arbitrary depth
See How do I unwrap an arbitrary number of nested Option types?
fn flatten<T>(x: Option<Option<T>>) -> Option<T> {
x.unwrap_or(None)
}
In my case, I was dealing with an Option-returning method in unwrap_or_else and forgot about plain or_else method.