Skip to content

Instantly share code, notes, and snippets.

@jlgerber
Last active April 10, 2019 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlgerber/4aefe36d92746838d646fcae1779da53 to your computer and use it in GitHub Desktop.
Save jlgerber/4aefe36d92746838d646fcae1779da53 to your computer and use it in GitHub Desktop.
compose functions in rust
// from
// https://stackoverflow.com/questions/45786955/how-to-compose-functions-in-rust
// answered by Jan Nils Ferner
//
// composes functions. In the orig namespace
mod orig {
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))
}
}
// explicitly compose two functions. same as orig::copose
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))
}
// a macro to add composing arbitrary numbers of functions
macro_rules! compose {
( $last:expr ) => { $last };
( $head:expr, $($tail:expr), +) => {
compose_two($head, compose!($($tail),+))
};
}
// compose two functions together
fn test_two() {
let add_and_multiply = orig::compose(|x| x * 2, |x| x + 2);
let divide_and_subtract = orig::compose(|x| x / 2, |x| x - 2);
let finally = orig::compose(add_and_multiply, divide_and_subtract);
println!("Result is {}", finally(10));
}
// lets add the macro above to handle multiple functions
fn test_multiple() {
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));
}
fn main() {
// orig
test_two();
// with macro
tets_multiple();
}
@jlgerber
Copy link
Author

referenced in this week in rust episode 281

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment