4 ms·
>I've lost count of how many times in Rust I had an "o: Option<(A, B)>" and a "f: fn(A, B) -> C" and couldn't call "o.map(f)" Non-serious solution: #![fea
by Arnavion 5y ago
>I've lost count of how many times in Rust I had an "o: Option<(A, B)>" and a "f: fn(A, B) -> C" and couldn't call "o.map(f)"
Non-serious solution:
#![feature(fn_traits, unboxed_closures)]
pub fn foo<Args, C>(o: Option<Args>, f: impl FnOnce<Args, Output = C>) -> Option<C> {
o.map(|v| f.call_once(v))
}
https://doc.rust-lang.org/stable/std/ops/trait.FnOnce.html https://doc.rust-lang.org/stable/std/ops/trait.FnOnce.html
"Non-serious" because it won't be stable any time soon, and it's not as concise as `o.map(f)` anyway.
More seriously, I don't think `o.map(f)` will ever happen, because it'll be backward-incompatible in the case of `o: Option<(T,)>` and `f: <U>impl FnOnce(U)` - `U` used to be `(T,)` and now would be `T`. Something like `o.map(spread(f))` might work if vararg generics are added to allow a generic `spread` that works for any tuple and matching-arity FnOnce.
- yakubin 5y ago[EDIT: comment applicable only to an older version of the parent comment] This "foo" still suffers from the same problem as "Option::map" does: it is hard-coded for functions of fixed arity (2 in this case, 1 in Option::map's case). Needing to write this function doesn't shorten the code. The SML-inspired solution allows one to write an "Option::map" which accepts functions of all possible arities (since they are all 1). But yes, if there are a lot of places where I want to call "Option::map" for an "f" which takes 2 arguments, that could work. Although, personally, I think I'd still opt for an explicit lambda, in order to communicate intent more directly (avoid one level of indirection).
- Arnavion 5y ago>This "foo" still suffers from the same problem as "Option::map" does: it is hard-coded for functions of fixed arity (2 in this case, 1 in Option::map's case). Hence the last paragraph in my comment.
- Animats 5y agoThere's o.expect("Error")?.map(f) if you just need to convert a Option to a value in-line and None is an error.
- Animats 5y agoAlso the rather bulky o.ok_or_else(|| anyhow("Error"))?.map(f) I've been writing too many of those forms lately, decoding a tree data structure of known form which might be wrong, but usually isn't.
- Arnavion 5y agoI assume you meant `.ok_or`, not `.expect`. Either way, I'm not really how this or your `.ok_or_else` comment is relevant to this sub-thread. `.map` is not a method on tuples.