pub trait Then<U, F: Fn(Self) -> U> where Self: Sized {
fn then(self, fx: F) -> U;
}
impl<T: Sized, U, F: Fn(T) -> U> Then<U, F> for T {
#[inline]
fn then(self, fx: F) -> U {
fx(self)
}
}
// for demonstration
fn main() {
(2 as u32).then(|r| assert_eq!(r, 2));
().then(|r| assert_eq!(r, ()));
let mapped: u32 = (10 as u8).then(|r| r as u32);
}
It surprised me that this functional trait didn't exist for arbitrary sized types (none that I could find). Why wasn't this created in standard library? There are some cases when having this functional code-flow makes code easier to understand. E.g:
fn input<T, E>(res: Result<T, E>) -> u32 {
res
.map_or_else(|err: E| getSomeUErr(err), |ok: T| getSomeUOk(ok))
.then(|u| processSomeU(u))
.then(|u| transformation0(u))
.then(|u| transformation1(u))
.then(|u| transformation2(u))
}
We could easily just wrap processSomeU
around the getSomeUErr
or getSomeUOk
functions, but ... it is indeed conceivable that the code is easier to read when using the functional style displaying the execution of function transformations one-by-one. Since then
is inlined, performance shouldn't be compromised. What do y'all think?