I want to implement function composition in an object method chain in Rust.
Before that, I confirmed that implementation of an object method chain for "pipe" of function application is possible in Rust as follows:
https://docs.rs/apply/0.2.2/apply/trait.Apply.html
trait Pipe: Sized {
fn pipe<F, B>(self, f: F) -> B
where
F: FnOnce(Self) -> B,
{
f(self)
}
}
impl<T> Pipe for T {}
fn main() {
let string = 1.pipe(|x| x * 2).pipe(|x| x + 1).pipe(|x| x.to_string());
println!("{}", string);
}
Now, the code of function composition is How to compose functions in Rust?
fn compose<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
fn main() {
let multiply_and_add = compose(|x| x * 2, |x| x + 2);
let divide_and_subtract = compose(|x| x / 2, |x| x - 2);
let finally = compose(multiply_and_add, divide_and_subtract);
println!("Result is {}", finally(10));
}
So the goal would be
let composed_f = (|x| x * 2).compose(|x| x + 1).compose(|x| x.to_string());
and what is the proper code to implement function composition in an object method chain in Rust like "pipe"?
EDIT
for function composition macro quoted from https://stackoverflow.com/a/45792463/11316608
macro_rules! compose {
( $last:expr ) => { $last };
( $head:expr, $($tail:expr), +) => {
compose_two($head, compose!($($tail),+))
};
}
fn compose_two<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
fn main() {
let add = |x| x + 2;
let multiply = |x| x * 2;
let divide = |x| x / 2;
let intermediate = compose!(add, multiply, divide);
let subtract = |x| x - 2;
let finally = compose!(intermediate, subtract);
println!("Result is {}", finally(10));
}
FnMutwhen possible. There's no reason to restrict callers toFnOnce.