Skip to content

Instantly share code, notes, and snippets.

@jlgerber
Last active April 10, 2019 13:45
Show Gist options
  • Select an option

  • Save jlgerber/4aefe36d92746838d646fcae1779da53 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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