Skip to content

Instantly share code, notes, and snippets.

@Yoplitein
Last active August 11, 2023 00:55
Show Gist options
  • Save Yoplitein/ca5d4519aa9034b3920f0265af2a6c88 to your computer and use it in GitHub Desktop.
Save Yoplitein/ca5d4519aa9034b3920f0265af2a6c88 to your computer and use it in GitHub Desktop.
#![feature(return_position_impl_trait_in_trait)]
trait ComposableOnce<From, To>: FnOnce(From) -> To {
fn compose_once<Final>(self, rhs: impl FnOnce(To) -> Final) -> impl FnOnce(From) -> Final;
}
impl<From, To, Func: FnOnce(From) -> To> ComposableOnce<From, To> for Func {
fn compose_once<Final>(self, rhs: impl FnOnce(To) -> Final) -> impl FnOnce(From) -> Final {
move |v| rhs(self(v))
}
}
trait ComposableMut<From, To>: ComposableOnce<From, To> + FnMut(From) -> To {
fn compose_mut<Final>(self, rhs: impl FnMut(To) -> Final) -> impl FnMut(From) -> Final;
}
impl<From, To, Func: FnMut(From) -> To> ComposableMut<From, To> for Func {
fn compose_mut<Final>(mut self, mut rhs: impl FnMut(To) -> Final) -> impl FnMut(From) -> Final {
move |v| rhs(self(v))
}
}
trait Composable<From, To>: ComposableMut<From, To> + Fn(From) -> To {
fn compose<Final>(self, rhs: impl Fn(To) -> Final) -> impl Fn(From) -> Final;
}
impl<From, To, Func: Fn(From) -> To> Composable<From, To> for Func {
fn compose<Final>(self, rhs: impl Fn(To) -> Final) -> impl Fn(From) -> Final {
move |v| rhs(self(v))
}
}
#[test]
fn test_composition() {
let succ = |v: i32| v + 1;
let test = Option::unwrap.compose(succ);
assert_eq!(test(Some(1)), 2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment