I have this function that works:
fn compose<A, B, C>(f: impl Fn(A) -> B, g: impl Fn(B) -> C) -> impl Fn(A) -> C {
move |x: A| g(f(x))
}
I'd like to use currying in this situation, so that I can do:
/* THIS */
compose(f)(g)(x)
/* Instead of this */
compose(f, g)(x)
Is it even reasonable to think about making a macro such that this is possible?
compose(f)(g)(h)···(x)
I've managed to get something that's kinda similar to what I want:
fn compose<A, B, C, F: 'static, G: 'static>(f: F) -> impl Fn(G) -> Box<dyn Fn(A) -> C>
where
F: Fn(A) -> B + Copy,
G: Fn(B) -> C + Copy,
{
move |g: G| Box::new(move |x: A| g(f(x)))
}
let inc = |x| x + 1;
let mult2 = |x| x * 2;
let inc_compose = compose(inc);
println!("{}", inc_compose(mult2)(3)); // 8
Now there's a new problem: when creating a higher-order function based on my compose
function, I need to give the function a type dependent on another function:
let inc = |x: usize| x + 1;
let mult2 = |x: usize| x * 2;
let mult3 = |x: usize| x * 3;
let inc_compose = compose(inc);
println!("{}", inc_compose(mult2)(3)); // 8
println!("{}", inc_compose(mult3)(3)); // ERROR: [rustc E0308] [E] mismatched types
Is there a way to avoid this error?
None of these similar posts answer my question:
- How do I emulate Lisp (apply) or (curry) in Rust?
- How to implement a multiple level currying function in Rust?
- How to invoke a multi-argument function without creating a closure?
The main reason is that I want currying to get the ability to do point-free programming.