Search code examples
rustmacrosfunction-composition

Function composition chain with a pure macro in Rust


I've read

How to compose functions in Rust?

Function composition chain in Rust

I've learned implementing a Function composition chain in Rust is rather difficult, and people use Macro with some function, however, I wonder if it's possible to use only a macro without a compose function from the first place.

I mean

compose!(f, g) can be simply reritten to |x| g(f(x)) (just another syntax)

or

compose!(f, g, h) can be similarly rewitten to |x| h(g(f(x)))

compose!(f, g, h, i) can be similarly rewitten to |x| i(h(g(f(x))))

compose!(f, g, h, i,...) can be similarly rewitten to |x| ...(i(h(g(f(x)))))

as the recursive manner.

I guess this recursive macro does not need the actual function composition function. I've just started learning Rust macro, so what would be the smart way to code this?

PS. Does the type-inference work fine with macro in Rust?


Solution

  • Yes, you can do that only using macros:

    macro_rules! compose {
        ($($rest:ident),+) => {
            |x| { compose!(expand x, $($rest),*) }
        };
        (expand $inner:expr, $function:ident, $($rest:ident),*) => {
            compose!(expand $function($inner), $($rest),*)
        };
        (expand $inner:expr, $function:ident) => {
            $function($inner)
        };
    }
    
    let a = compose!(f, g, h, i);
    //expands into:
    let a = |x| i(h(g(f(x))));